Monday, August 1, 2016

[Salesforce / Lightning] Geolocation Fun with Location Aware Lightning Components

Summer 16 platform release came up with Automatic Geocodes for Addresses: your Accounts, Contacts and Leads addresses are now automatically geocoded using Data.com.

This means that the Latitude, Longitude and Accuracy fields are automatically populated after an address is filled (more details here).

Let's combine this awesome new feature with Lightning Components to create a component to show the nearest accounts (using the Billing Address) to the Company location.

TL;DR here is the Github repository.

To achieve this we have to make few configurations to enable the new feature.

At first activate the Data.com Clear Rules for the Account's Billing Address:


This means that when a new Account is created and the the Billing Address is filled in, Data.com will try to geolocate the address and fill the BillingLongitude, BillingLatitude and BillingAccuracy fields.

We want to use the Company geolocation as the "center" of the geo-search; unfortunately Data.com cleans Accounts, Contacts and Leads address only.

We can update the Organization's Latitude, Longitude fields manually: unfortunately these fields are updatable via SOAP API only.

To do this grab a valid Salesforce session id. The easiest way is to grab it from an open Salesforce tab using your browser's developer console:


You also need your ORG's ID: you can pick it up from Setup > Company Information or by simply querying Select Id From Organization.

Open your favorite request maker app (e.g. Request Maker) and make the following SOAP call:

Method: POST
Endpoint: https://your_org_instance/services/Soap/c/37.0/
Headers:
    Content-Type: text/xml; charset=utf-8
    SOAPAction: update
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
 xmlns:urn="urn:enterprise.soap.sforce.com" 
 xmlns:urn1="urn:sobject.enterprise.soap.sforce.com"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Header>
      
      <urn:SessionHeader>
         <urn:sessionId>SESSION_ID</urn:sessionId>
      </urn:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <urn:update>
         <urn:sObjects xsi:type="urn1:Organization">
            <Id>ORG_ID</Id>
            <Longitude>9.114845271216465</Longitude>
            <Latitude>39.21264936045958</Latitude>
         </urn:sObjects>
      </urn:update>
   </soapenv:Body>
</soapenv:Envelope>

The component we are going to build is based on Creating a Salesforce Lightning Map Component By Christophe Coenraets.

The component will query for accounts whose location is inside a given radius in km/mi.

The first thing is to create an Apex Class capable of this query, the AccountsOnMapController, which includes the following query:

Organization orgDetails = [SELECT Id, Longitude, Latitude FROM Organization WHERE Id = :UserInfo.getOrganizationId()];
result.accounts = [Select Id, Name, BillingStreet, BillingCity, BillingCountry, BillingState, BillingPostalCode,
                BillingLatitude, BillingLongitude From Account Where BillingLatitude != null
    and DISTANCE(BillingAddress, GEOLOCATION(:orgDetails.Latitude, :orgDetails.Longitude), 'km') < :radius];
The component uses the Leaflet JS library as well and outputs the pins of all accounts found within the radius:
Each pin is clickable and in this simple implementation is capable of opening a new window with the given Account standard layout page:
The UI allow for radius and units modification, to query for different distances:

This component shows how easy is to play with location aware components, take it and add as many new features as you like!