Wednesday 25 December 2013

Google Map Integration With Salesforce

I got a requirement of showing google map of Account Billing address on detail page of Account. In the starting I was thinking how to do it, but didn't get anything, but now at the end I tried this below code and everything is working as fine as visible down there.

In this below scenario user don't have to submit their APIKey of Google Map to get the Map of the Address. and one more thing here am not using any Controller/Apex class only and only page is doing everything.

Here it is the Detail Page of Account and the Location of Account billing address using Google Map


Below is the Visual force Page

<!--
/**
* Description : Component for showing google map of Account Address.
*
* Created Date : 12/25/2013
*
* Created By : Abhi Tripathi
*
* Version : V1_0
**/
-->
<apex:page standardController="Account">
    
    <!-- Import Necessary Jquery js File and StyleSheets-->
    <apex:includeScript value="{!URLFOR($Resource.jQuery_GoogleMap, 'js/GSensor.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.jQuery_GoogleMap, 'js/jquery-1.6.2.min.js')}"/>
    <script>
    var map,geocoder,infowindow;
    var latLngs = [];
    $j = jQuery.noConflict();
    $j(document).ready(function(){
        initialize();
    });
    
    function initialize() {
        geocoder = new google.maps.Geocoder(37.09024, -95.712891);
        //initial cordinates for map init
        var latlng = new google.maps.LatLng();
        var myOptions = {
            center: latlng,
            zoom: 2,
            maxZoom: 14,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        
        //load the map
        map = new google.maps.Map($j('#map')[0], myOptions);
        codeAddress();
    }
    
    /*This function codes the address using the Billing Address in the Acoount*/
    function codeAddress(){
        //prepare a string for geocoding
        var address = '{!JSENCODE(Account.BillingStreet)},{!JSENCODE(Account.BillingCity)},{!JSENCODE(Account.BillingCountry)},{!JSENCODE(Account.BillingPostalCode)}';
        console.log(address);
        
        //geocode the address
        geocoder.geocode( { 'address': address }, function(results, status) {
            //if it is a success
            if (status == google.maps.GeocoderStatus.OK) {
                var location = results[0].geometry.location;
                var marker=addMarker(location );
            }
            else {
                // alert(status);
            }
        });
    }
    
    /*
*This method adds a marker to the provided location
**/
    function addMarker(location) {
        marker = new google.maps.Marker({
            position: location,
            map: map
        });
        //set the bounds and initial zoom
        var latlngbounds = new google.maps.LatLngBounds();
        latlngbounds.extend(marker.getPosition());
        map.fitBounds(latlngbounds);
        map.setZoom(14);
        return marker;
    }
    
    </script>
    <style>
        #map {
        width:100%;
        height:500px;
        margin-left:59.5%;
        }
    </style>
    <div id="map" class="ui-widget-content ui-corner-all ui-state-default"></div>
</apex:page>


Save that above code before that save this Jquery files and after that save them into your static resource with their corresponding name

Click Below Links for the JQuery files

GSensor
jquery-1.6.2.min
jquery-ui-1.8.16.custom.min

After saving the above jquery files in Static Resource and saving your visualforce page.

Go to
Customize --> Accounts --> Page Layout --> Edit(One of page layout) --> Visualforce Pages(sidebar of layout)

Search your page and add it to the page layout. and see the magic
Note: Billing address need to be filled with correct addres otherwise its will show a default map.

Happy Coding..!!

Tuesday 24 December 2013

Parsing XML file in Apex Class

Somedays ago I was in need to parse the XML response, Which I was getting in reponse. it require a bit labour to get a particular value from that XML file.

In salesforce most of the time when we are working with webservice, we need to parse JSON or XML. So here I am doing a small POC of parsing XML file in salesforce.
Here am trying to fetch the value of "R10TnxID" from the file.

So below is the code, for more detail you can visit on This Link
Here you need learn a bit about DOM

/** Description : Parse XML file. String Response is the XML file which is going to be parsed.
*
* Created By : Abhi Tripathi 
*
* Created Date : 07/09/2013
*
* Revisison Log : 07/09/2013 
*
* Version : V1.0
**/
public with sharing class domXmlParsing {
    
    //method to parse xml file 
    public static string walkThrough(){
        
        //XML string to parse
        String response = '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">'
            + '<S:Body>'
            + '<wss:createPendingTicketResponse xmlns:wss="http://www.boomi.com/connector/wss">'
            + '<wss:createPaymentTransctionLogResponse/>'
            + '<PendingTicket xmlns:pay="http://www.boomi.com/v1b/Payment">'
            + '<pay:Response>'
            + '<pay:R10TillID>test001</pay:R10TillID>'
            + '<pay:R10SequenceNumber>test002</pay:R10SequenceNumber>'
            + '<pay:SFTnxId>test003</pay:SFTnxId>'
            + '<pay:R10TnxID>'+ 'TESTME' +'</pay:R10TnxID>'
            + '<pay:Org>test004</pay:Org>'
            + '</pay:Response>'
            + '</PendingTicket>'
            + '</wss:createPendingTicketResponse>'
            + '</S:Body>'
            + '</S:Envelope>';
        
        //dom
        Dom.Document doc = new Dom.Document();
        
        //string
        string result;
        
        //load document
        doc.load(response);
        
        Dom.XMLNode envelope = doc.getRootElement();
        system.debug('!!!!!!!!! value of envelope' + envelope);
        
        //body
        Dom.XMLNode body = envelope.getChildElement('Body', 'http://schemas.xmlsoap.org/soap/envelope/'); 
        system.debug('@@@@@ value of body' + body);
        
        //child element of createPendingTicketResponse
        Dom.XMLNode createPendingTicketResponse = body.getChildElement('createPendingTicketResponse', 'http://www.boomi.com/connector/wss'); 
        system.debug('@@@@@ value of createPendingTicketResponse' + createPendingTicketResponse);
        
        //child element of createPaymentTransctionLogResponse
        Dom.XMLNode createPaymentTransctionLogResponse = createPendingTicketResponse.getChildElement('createPaymentTransctionLogResponse', 'http://www.boomi.com/connector/wss'); 
        system.debug('@@@####@@ value of createPaymentTransctionLogResponse' + createPaymentTransctionLogResponse);
        
        //child element of pending Ticket
        Dom.XMLNode PendingTicket = createPendingTicketResponse.getChildElement('PendingTicket', null); 
        system.debug('@@@####@@ value of PendingTicket' + PendingTicket);
        
        //child element of Response 
        Dom.XMLNode Respon = PendingTicket.getChildElement('Response', 'http://www.boomi.com/v1b/Payment'); 
        system.debug('@@@####@@ value of Response' + Respon); 
        
        //child element of R10TnxID
        Dom.XMLNode R10TnxID = Respon.getChildElement('R10TnxID', 'http://www.boomi.com/v1b/Payment'); 
        system.debug('@@@####@@ value of R10TnxID' + R10TnxID); 
        
        //here is the value in R10TnxID
        result = R10TnxID.getText();
        system.debug('@@@####@@ value of result' + result); 
        
        return result;
    }
}


After saving this above class, go to your Developer Console and write as below shown and then check your debug logs, you'll get the value of R10TnxID


Happy Coding....!!!!!!

Friday 13 December 2013

Salesforce Comparable Interface Using It to Sort Wrapper Class

Salesforce have an Interface named as "Comparable" , it is used to add List sorting support for your Apex class

To know more about the Comparable click on this link Comparable Interface

So I used it to compare created date of my history Account records , I have a picklist name Grade__c on Account, whenever user change it , saleforce created a history record for that change.

Note : You need to activate the history tracking for Account and for that field too, for which you want history tracking.

So now am going to tell you how my code works,

Whenever user Updates OR change value of Grade on Account object it will be added on the report chart of history

Here is the snapshot of that report chart


For that I have created a main class and as well as a wrapper class

Wrapper Class
 /**  
 * Description : Controller class for page of Account History of Grade  
 *  
 * Created Date : 12/10/2013  
 *  
 * Created By : Abhi Tripathi  
 *  
 * Version : V1.0   
 **/  
 global class AccountHistoryWrapper implements Comparable{  
   public Account account {get; set;}  
   public List<AccountHistory> accountHistories {get; set;}  
   //Calling Constructor  
   global AccountHistoryWrapper(Account account, List<AccountHistory> accountHistories) {  
     this.account = account;  
     this.accountHistories = accountHistories;   
   }  
   // Compare opportunities based on the opportunity amount.  
   global Integer compareTo(Object compareTo) {  
     // Cast argument to AccountHistoryWrapper  
     AccountHistoryWrapper aHW = (AccountHistoryWrapper)compareTo;  
     // The return value of 0 indicates that both elements are equal.  
     Integer returnValue = 0;  
     if ( aHW.account.CreatedDate > aHW.account.CreatedDate) {   
       // Set return value to a positive value.  
       returnValue = 1;  
     } else if ( aHW.account.CreatedDate < aHW.account.CreatedDate) {  
       // Set return value to a negative value.   
       returnValue = -1;   
     }  
     return returnValue;   
   }  
 }  

Here is the Controller Class

 /**   
 * Description : Controller class for page of Account History of Grade   
 *   
 * Created Date : 12/10/2013   
 *   
 * Created By : Abhi Tripathi   
 *   
 * Version : V1.0    
 **/   
 public class AccountHistoryController {   
   public List<AccountHistoryWrapper> accountHistoriesWrapList {get; set;}   
   //Calling cosnturctor   
   public AccountHistoryController() {   
     //Memory Allocation   
     accountHistoriesWrapList = new List<AccountHistoryWrapper>();   
     //Loop through Accounts   
     for(Account acc : [Select Id, Name, CreatedDate, (Select ID, Field, AccountId, CreatedDate, Createdby.Name, Oldvalue,    
                              Newvalue, Account.Name From Account.Histories   
                              Where Field = 'Grade__c' ORDER BY CreatedDate DESC LIMIT 200 )   
               FROM Account ORDER BY LastModifiedDate DESC]) {    
                 //Populate wrapper list with values   
                 if(acc.Histories.size() > 0)   
                   accountHistoriesWrapList.add(new AccountHistoryWrapper(acc, acc.Histories));    
               }   
     //Get List of wrapper and sort it   
     accountHistoriesWrapList.sort();    
   }   
 }   

Here is the Page

 <!--   
 /**  
 * Description : Custom VF page to add it on store page layout as an inline VF page.  
 *  
 * Created By : Abhi Tripathi  
 *  
 * Created Date : 12/10/2013  
 *  
 **/  
 -->  
 <apex:page controller="AccountHistoryController">  
   <apex:form >  
     <apex:pageBlock >  
       <table cellspacing="0" border="0" class="detailList list" cellpadding="0">  
         <thead class="rich-table-thead">  
           <tr class="headerRow">  
             <th class="headerRow" scope="col">Activity</th>  
             <th class="headerRow" scope="col">Date</th>  
             <th class="headerRow" scope="col">Change By</th>  
           </tr>  
         </thead>  
         <tbody>  
           <apex:repeat value="{!accountHistoriesWrapList}" var="accountHistoryWrap">  
             <tr class="dataRow even first" onmouseover="if (window.hiOn){hiOn(this);} " onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}">  
               <td colspan="3" style="text-align:center"><B><font size="3"><em><apex:outputField value="{!accountHistoryWrap.account.Name}"/></em></font></B></td>  
             </tr>  
             <apex:repeat value="{!accountHistoryWrap.accountHistories}" var="aHW">  
               <tr class="dataRow even first" onmouseover="if (window.hiOn){hiOn(this);} " onmouseout="if (window.hiOff){hiOff(this);} " onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}">  
                 <td class="dataCell">  
                   Changed Grade from <b>"{!aHW.oldvalue}"</b> to <b>"{!aHW.newvalue}"</b>   
                 </td>  
                 <td class="dataCell">  
                   <apex:outputField value="{!aHW.createddate}"/>   
                 </td>  
                 <td class="dataCell">   
                   <apex:outputField value="{!aHW.createdby.Name}"/>   
                 </td>  
               </tr>   
             </apex:repeat>  
           </apex:repeat>  
         </tbody>  
       </table>  
     </apex:pageBlock>  
   </apex:form>  
 </apex:page>  

Test class

 @isTest(seeAllData=false)  
 private class Test_AccountHistoryController {  
   //Test method  
   static testMethod void myUnitTest() {  
     //List of Account  
     List<Account> accountList = new List<Account>();  
     //Insert Account  
     Account account = new Account(Name = 'test', Grade__c = 'A');  
     insert account;  
     //Insert another account  
     Account account2 = new Account(Name = 'ATest', Grade__c = 'C');  
     insert account2;  
     //Update Account  
     account.Grade__c = 'B';  
     accountList.add(account);  
     //Update Account  
     account2.Grade__c = 'D';  
     accountList.add(account2);  
     //Update account  
     update accountList;  
     //Account History  
     List<AccountHistory> accHistory = [Select Id From AccountHistory Where AccountId =: accountList];  
     //Test starts here  
     Test.startTest();  
     //Calling wrapper class  
     AccountHistoryWrapper wrapper = new AccountHistoryWrapper(account, accHistory);   
     //Controller  
     AccountHistoryController controller = new AccountHistoryController();  
     //Test stops here  
     Test.stopTest();  
     //Assert  
     System.assertEquals(true, Controller.accountHistoriesWrapList != null);  
   }  
 }  


Happy Coding
CHEERS........!!!!!!!