Thursday, April 26, 2012

Auto-filling City and State with Postcode Anywhere and Marketo

First, the "product": an HTML script block that can be added to Marketo as a snippet for looking up the City and State/Province based on a given Country and Zip/Postal Code! All one has to do to use it should be to edit and change the Postcode Anywhere license key.

The background for this is that our Marketing department went live with Marketo last week, and that was an awesome accomplishment which involved replacing all of our previous Web-to-Lead forms with Marketo landing pages. With that done, we set our eyes on a next step: making our forms more approachable by automatically filling in a lead's city and state/province if they give us the country and zip/postal code.

For the lookup service, we chose Postcode Anywhere originally because they were listed on the Salesforce AppExchange. But then we realized that the app was for internal use after a lead already went into Salesforce, and what we actually want is for the info to be filled in before a form is even submitted. Plus, we want our leads to go into Marketo first, not Salesforce.

Knowing that our marketers should not have to know JavaScript to use this functionality, it was obvious that any real solution would have to be able to be dragged and dropped on to a Marketo landing page with minimal configuration, if any at all.

Thankfully, it appears that there are standard address fields in Marketo with standard and consistent name and id attributes. Once I discovered this common characteristic across all forms that we had created, it was simple to customize the JavaScript code template that Postcode Anywhere publishes to work with Marketo.

This is a great example of two companies, Marketo and Postcode Anywhere, making user-friendly integration a viable and attractive option.

Monday, April 2, 2012

SObject Utility Class Template

Have you ever had to get the ID of a record type for a specific object? Or have you needed to hard-code a particular picklist value into a Visualforce controller/extension or other Apex class? I've had to do both on a fairly regular basis, and it soon became apparent that stress-related health problems may arise if I ever have to refactor my code, or if a user requests a change in picklist values.

To address this issue, it seems that setting up a global constant accessible to all Apex classes would be hugely valuable in making sure that picklist values and record types (and other items) are consistently referenced in Apex.

For example, if I'm trying to set the Status of a Contract to "Activated", I could write the code as follows:
myContract.Status = 'Activated';

This is great if it's the only place I ever deal with the Contract Status field. But what're the chances of that? Instead, how about writing the code as follows?
myContract.Status = ContractUtil.ACTIVATED_STATUS;

Now I don't need to worry about all the myriad places where I've hardcoded the status value. If I ever need to change the status, I can update the constant in ContractUtil or look for all references to ContractUtil.ACTIVATED_STATUS.

Here's the sample code for a generic SObject utility class:
/**
 * Utility class with supporting methods for
 * a Salesforce SObject.
 *
 * Examples of supporting methods include getting
 * a Record Type ID, getting an expected picklist
 * value for a particular field, and conversion
 * to/from other objects.
 */
public class GenericSObjectUtil {

    /**
     * The String value that
     * represents an activated status, which goes
     * into the Status field.
     */
    public static final String ACTIVATED_STATUS =
            'Activated';

    /**
     * The expected default Record Type Name
     * for all users.
     */
    public static final String DEFAULT_RECORD_TYPE_NAME =
            'This SObject';

    /**
     * The String value that
     * represents a draft status, which goes
     * into the Status field.
     */
    public static final String DRAFT_STATUS =
            'Draft';

    /**
     * The map of RecordTypeInfo
     * objects retrieved by describing the
     * SObject, keyed by the Record Type Name.
     * 
     * This is stored to make
     * getRecordTypeId method calls
     * more efficient.
     */
    private static final Map recordTypeInfosByName =
            Schema.SObjectType.Contract.getRecordTypeInfosByName();

    /**
     * Retrieve the Record Type ID based on a
     * given Record Type Name.  If no match is
     * found, then return null.
     *
     * @param  name The name of the Record Type
     * @return      The ID of the Record Type,
     *              if found; null otherwise.
     */
    public static Id getRecordTypeId(String name) {
        return recordTypeInfosByName.get(name).getRecordTypeId();
    }   // public static Id getRecordTypeId(String)
}   // public class GenericSObjectUtil

Note: I know the above code may be cut off a bit due to width limits in Blogger, but you should be able to copy and paste the code into a text editor to see the full structure if necessary.

What do you think? Feedback on this implementation or other solutions will be appreciated!