Monthly Archives: July, 2015

Showing Aggregate Result In VisualForce Page

Suppose by some Custom logic, you’ve already calculated  Count of Contacts for each Account. Your Account has two record Type ‘Bus Rec Type’ and ‘Person Rec Type’. Now on Visual force page you want to display  Total number of Contacts’ for each Record Type.

Now Count of Contacts for each record type can be easily found using aggregate Query on Controller But we sometimes get stuck how to display Aggregate Result in Visual force Page

The Answer of this problem is : Wrapper Class You’ve to add Result of Aggregate Query in ‘List of objects of Wrapper Class’. and then show the result in VF page.

Showing below how we can do it, using above example Below is Your VF Page : It is showing list in VF Page.

<apex:page controller="AccAggregat">
<apex:datatable value="{!wlist}" var="a" >
<apex:column headerValue="Recordtype by Name " value="{!a.Rtype }" />
<apex:column headerValue="CountValue" value="{!a.count}" />

</apex:datatable>
</apex:page>

Now code of controller: 

public class AccAggregat {

Public aggregateResult[] agresult;
public list<WrapperClass> wlist{get;set;}

public AccAggregat() {

//This Query calculating Aggregate Result 
agresult = [select recordType.Name RecType, sum(Count_of_Contacts__c) Allcon 
from Account group by recordType.Name];
//Here we're populating  list of Wrapper class with Data from Aggregate result
//We'll use this wrapper class list in VF Page

wlist = new list<WrapperClass>();
For ( aggregateResult ag :agresult)
wlist.add(new WrapperClass((String)ag.get('RecType'), (Decimal)ag.get('Allcon')));
}

//This is wrapper class containing data to be shown on VF page
public class WrapperClass
{
public string Rtype{get;set;}
public Decimal count{get;set;}

Public WrapperClass( string Recordtype, Decimal cnt)
{
this.Rtype = RecordType;
this.count = cnt;
}
}
}

Few points to Remember:

  1.  In Wrapper Class,  use getter and setter for variables, which are shown on VF page.
  2. Note syntax to create new object, which is added in List of wrapper list:
  3. Note also syntax to get result  from Aggregate Object : ag.get(‘RecType’)

wlist.add(new WrapperClass((String)ag.get(‘RecType’), (Decimal)ag.get(‘Allcon’)));

Connecting one Salesforce Org to another via Rest API

I was thinking for long to publish this article. My initial purpose was to learn all major concepts behind Rest API.

Since I don’t have other apps available which I can use for connection so decided that I should Salesforce both as Sending(A) as well as Receiving org(B).

Apart from Rest API basics, This also gave me opportunity to learn following :

  • 1. Expose Apex Classes as REST Resource.
  • 2. JSON serialization and deserialization
  • 3. Making both POST as well as GET request for Rest API call.

We’ll start with ‘RECEIVING ORG CHANGES’

Step 1:  We’ll start with steps needed to configure receiving org(B). Business case : Opportunity is created and closed in ‘Receiving org(B) .After that an order is created outside receiving org. In our case , we ‘ll update Order Amount in  Account object in Receiving org(B) from data created in ‘Sending Org(A).

Step 2: Create a new class in  B . We’ll expose this class as rest resource, so that it can receive data and update Account

@RestResource(urlmapping = '/getAccountData/*')
global  class AccountRestService {
@httpGet
global static string DepositAmountviaGet()
{
integer DepositAmount = Integer.valueOf(RestContext.request.params.get('amount'));
String AccId = RestContext.request.params.get('AccountId');

list acclist = [select id, DevWorld__Deposit_Amount__c, DevWorld__Deposit_Date__c 
from account where id = :Accid];
if(acclist.size()==0)
return 'AccountNotFound';
else
{
try{
account a = acclist[0];//For sake of simplicity, consider handling on record.
a.DevWorld__Deposit_Amount__c = DepositAmount;
update a;

}
catch(exception e)
{
}
return 'Deposit updated succesfully';
}
}

Few points to be noted :

  • Class is declared as Global and method Global & Static
  • You’ve to use annotation   @RestResource with Url mapping as some string like get AccountData before Class declaration.Note the exact syntax. This URL mapping string will be used to create URL for making request from sending ORG.

                 @RestResource(urlmapping = ‘/getAccountData/*’)

  •   Note @httpget  annotation before method-  we’ll be calling this rest resource using ‘GET’ method of http request from API call of Sending org
  • This class will receive two parameters, AccountID, indicating which Account need to be updated and Deposit Amount.

Step 3:   Now since, another SFDC org has to call this rest resource, so we’ve to add ‘Salesforce as ‘connected org’ in this receiving org.

For this  follow below steps

  • Go to Setup | Create | Apps , create new connected App, say with name as ‘SendingSFDCOrg’. 
  • Fill other settings as shown in below screeshot. Important thing is you’ve to provide call back URL and Oauth Scopes.

Connected App

On Saving, you’ll get screen where Client Id and Client Secret will be available to you as shown below:

This client Id and secret will be used in the sending org for authentication.

ClientIdnSecret

Now we’ll move to the Sending Org changes

Step 1:   Create a New VF Page which will show2 fields to enter

AccountID –  User will enter ‘ID’ of some account in receiving org.
Deposit Amount – User will enter Deposit amount to be updated in receiving org.

<apex:page controller="clsSubmitDatainOtherOrg">
<apex:form >
<apex:pageblock >
<apex:pageblockSection >
<apex:inputtext label="Enter Account Id" value="{!AccountId}" />
<apex:inputtext label="Enter Deposit Amount" value="{!depositAmount}" />
</apex:pageblockSection>

<apex:commandButton value="Submit Data" Action="{!SubmitDataUsingGet}"/>
</apex:pageblock>
</apex:form>
</apex:page>

Step 2: Update Controller with following code :

public class clsSubmitDatainOtherOrg {

// we'll be making Oauth Request first to get token,
// One we've token we'll make Rest API call to get data updated in target Org.
public Integer depositAmount{get;set;}
public string AccountId{get;set;}

// This four variables are required for authentication to Oauth Token
String clientId = 'Your Client Id copied from Receiving Org' ;
String clientSecret = 'Your client Secret copied from Receiving Org';
String username= 'Your User Id';
String password= 'your Pwd';

//This method is called form VF page on Submit
public PageReference SubmitDataUsingGet() {

//using this request body we'll make API call
String reqbody = 'grant_type=password&client_id='+clientId+'&client_secret='
+clientSecret+'&username='+username+'&password='+password;

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setBody(reqbody);
req.setMethod('POST');
req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
//Note if my domain is set,use the proper domain name else use login.salesforce.com
// for prod or developer environment, and test.salesforce.com for sandbox

HttpResponse res = h.send(req);
OAuth2 objAuthenticationInfo =(OAuth2)JSON.deserialize(res.getbody(), OAuth2.class);

// proceed further only if you get token
if(objAuthenticationInfo.access_token!=null){

// First create http and req object and set EndPoint
// Note Endpt, this part is common' https://ap1.salesforce.com/services/apexrest/
//'getAccountData' name is URLMapping you set while creating Rest 
//resource in Receiving org.

Http h1 = new Http();
HttpRequest req1 = new HttpRequest();
string EndPt = 'https://ap1.salesforce.com/services/apexrest/getAccountData?' +
'AccountId='+AccountId+'&amount='+depositAmount ;

// Set request header to send token, setMethod, and set Endpoint
req1.setHeader('Authorization','Bearer '+objAuthenticationInfo.access_token);
req1.setMethod('GET');
req1.setEndpoint(EndPt);


//finally make a call
HttpResponse res1 = h1.send(req1);
system.debug('RESPONSE_BODY'+res1 .getbody());
}
return null;
}
}

If you’ve set everything correctly,  data will be updated in the target org.

We” learn how to connect using post method in next post

Connecting .NET Console Application to Salesforce via Enterprise WSDL

This was something I had done while doing POC around 2 years back. At that I had whole team to work with. Since I don’t have much idea about .NET, so I was contributing on Salesforce end and other guys proficient in .NET were mainly working. But we didn’t take much time to connect to Salesforce and make the connection working properly.

Few days back, I decided to do that myself. Because of my inadequate knowledge of .NET, it took me full  two days  to make it working. In this blogpost, I’m giving all steps(with code) to make the connection up and running. We’ll use Enterprise WSDL tO make describeGlobal call and return all objects present in SFDC

Step 1 : Install ‘VS Express 2013 for web. VS is Visual Studio. It is available for free  on the internet.

Step 2:  Once installed, Click File Menu to create New Project as shown below:

New Project in .NET Application

Create New Project in .NET Application

Step 3 :  In New Project window,  Select ‘Windows’ Application under Visual C# Option’.  Give Name to application something like ‘ConnectToSFDC or ConsoleSFDC etc ‘. see Screenshot below

Select Windows Application under Visual C# option

Select Windows Application under Visual C# option

Step 4:   After you click ‘OK’. Visual studio will create New Project with name you’ve provided.  There are multiple Frames in the project.  Right Side frame  is called Solution Explorer. Right click the name of the project and give ‘Output Type’ as ‘Console application’. Close the tab having same name as Project name. Step 5:  Your main project window will look like this :

Project Main Window

Project Main Window

Step 6:  Now we’ll have to add Enterprise WSDL so that we can Query, Create/Update records in SFDC For this login into SFDC,  Go to Setup | Develop | API . Download Enterprise WSDL.

Step 7: We now have to add WSDL in .NET Application  Right click name of the  Project and click  Add | Service Reference | Advanced..(option at bottom of the new popup)  |  Add Web reference. if you’ve correctly added the WSDL, then two things happen : 1. Window will show ‘SforceService’ Description window showing methods available in webservice to work with .For e.g  onvertLead, Create, delete etc. 2. Right side of web reference window will say ‘ Web services found at this URL’ with name of WSDL file. Showing this in below screen shot.  It will also give option to change the name of Webreference. Change it to sfdcConnect .Click Ok  in all the windows which have been opened and return back to Project Window

Step 8:  In the Code window, add name space

using System.Web.Services.Protocols;

Step 9: Now under Class1. which is default crated by .NET. Add following code . showing screen shot also

Main Code Window

Main Code Window

 
private connectToSFDC.SfdcConnect.SforceService binding;
    
    
    [STAThread]
        static void Main(string[] args)
        {
            Class1 sample = new Class1();
            sample.run();
        }

        public void run()
        {
            // Make a login call

            if (login())
            {
                // Do a describe global
                describeGlobalSample();
                // Describe an account object
                // describeSObjectsSample();
                // Retrieve some data using a query
                //querySample();
                // Log out
                //logout();
            }
        }
        private bool login()
        {
            Console.Write("Enter username: ");
            string username = Console.ReadLine();
            Console.Write("Enter password: ");
            string password = Console.ReadLine();
            // Create a service object
            binding = new connectToSFDC.SfdcConnect.SforceService();
            // Timeout after a minute
            binding.Timeout = 60000;
            // Try logging in
            connectToSFDC.SfdcConnect.LoginResult lr;
            try
            {
                Console.WriteLine("\nLogging in...\n");
                lr = binding.login(username, password);
            }
            // ApiFault is a proxy stub generated from the WSDL contract when
            // the web service was imported
            catch (SoapException e)
            {
                // Write the fault code to the console
                Console.WriteLine(e.Code);
                // Write the fault message to the console
                Console.WriteLine("An unexpected error has occurred: " + e.Message);



                // Write the stack trace to the console
                Console.WriteLine(e.StackTrace);
                // Return False to indicate that the login was not successful
                return false;
            }
            // Save old authentication end point URL
            String authEndPoint = binding.Url;
            // Set returned service endpoint URL
            binding.Url = lr.serverUrl;

         binding.SessionHeaderValue = new connectToSFDC.SfdcConnect.SessionHeader();
         binding.SessionHeaderValue.sessionId = lr.sessionId;
         printUserInfo(lr, authEndPoint);
            // Return true to indicate that we are logged in, pointed
            // at the right URL and have our security token in place.
            return true;

        }
private void printUserInfo(connectToSFDC.SfdcConnect.LoginResult lr, String authEP)
        {
            try
            {
                connectToSFDC.SfdcConnect.GetUserInfoResult userInfo = lr.userInfo;
                Console.WriteLine("\nLogging in ...\n");
                Console.WriteLine("UserID: " + userInfo.userId);

                Console.WriteLine();
                Console.WriteLine("SessionID: " + lr.sessionId);
                Console.WriteLine("Auth End Point: " + authEP);
                Console.WriteLine("Service End Point: " + lr.serverUrl);
                Console.WriteLine();
                Console.ReadLine();

            }

            catch (SoapException e)
            {
              Console.WriteLine("An unexpected error has occurred: " + e.Message +
              " Stack trace: " + e.StackTrace);
            }

        }

        private void describeGlobalSample()
        {
            try
            {

                SfdcConnect.DescribeGlobalResult dgr = binding.describeGlobal();
                Console.WriteLine("\nDescribe Global Results:\n");
                // Loop through the array echoing the object names to the console
                for (int i = 0; i < dgr.sobjects.Length; i++)
                {
                    Console.WriteLine(dgr.sobjects[i].name);
                }
            }
            catch (SoapException e)
            {
                Console.WriteLine("An exception has occurred: " + e.Message +
                "\nStack trace: " + e.StackTrace);
            }

            Console.ReadLine();
        }

Important :  Make sure that Visual Studio Editor shouldn’t be showing errors in the form of red line under code expressions.One of the main source of error is, if WSDL is not properly added as web reference. In case you face any problem. try deleting and adding web reference again. Try to check name of reference added and name used in your class code.

Step 10: As a next step, click on debug tab on top bar of VS editor and click ‘Start Debugging’. This will build the application and open and new window asking you to enter username and password, meant to connect to Salesforce.

once done it will provide list of all objects, which shows connection is working properly.