Saturday, August 20, 2011

Merge Field Functions in Email Templates

This may help to get people thinking about how much can be accomplished with text and HTML email templates before diving into Visualforce templates.

Did you know that you can substitute in text for blank values? By using the {!sObject.FieldName, substitute text including spaces} convention, blank values can be automatically replaced with default values.

Furthermore, it looks like at the email templates recognize at least two Visualforce-esque functions, demonstrated in the following examples:
  • {!NullValue(Lead.Name,"visitor")}, which is the same as the substitution described above
  • {!If(Lead.Name="Barack Obama","President","Citizen")}
  • {!If(IsPickVal(Lead.Status,"New"),"Super Important","Somewhat Important")}
Does anyone have any other information on what functions can be used in simple text or HTML email templates? Are all Visualforce functions available here, I wonder?

Tuesday, August 16, 2011

Reliably Getting Record Type ID's for Test Classes

I'm going to share this simple way of reliably getting a record type ID in Salesforce for testing purposes. Using this method will guarantee that the right record type is retrieved for the right object.

All one has to do in the test class is... get ready for the ridiculously long line of code...

private static final Id RECORD_TYPE_NAME_RECORD_TYPE_ID =
Schema.SObjectType.sObjectApiName.getRecordTypeInfosByName().get('Record Type Name').getRecordTypeId();


Thank you, Salesforce, for sObject Describe Results.

Saturday, August 13, 2011

Mixing Person Accounts, Contacts and Business Accounts

I really enjoy the excitement of learning new things, especially through active discussion and target questions and answers. One of the subjects that never lets me down in this area is the concept of person accounts in Salesforce.

Having raved about it in previous posts, I feel obliged to answer a question that was posed about how to actually use person accounts and business accounts in the same org.

The answer could be fairly straightforward: In the standard sales processes, there's no need to mentally make a big distinction between the two. Opportunities are tied to accounts, not to contacts. This means that if a salesperson is trying to close a deal, it doesn't matter if the deal is for a person or for another organization. The opportunity is what's important, and it's always related back to the account entity, person or organization, with which you're doing business.

A trickier question which we're running into at work is: What's the best way to handle people who are both your direct customers and who are contacts at other organizations? Theoretically, the idea of linking the contact to both the business account and to the person account would work. In practice, however, I think if an organization is investing time and energy into this level of constituent mapping, then it would be worthwhile to analyze the business needs and maybe setup some workflow, Apex and Visualforce to take advantage of the data links.

Not to dodge the question entirely, but I think that there are always specific organizational needs that drive people to setup more complex and complete data models. If anyone's interested in discussing a specific use case, I'd be totally game!

Thursday, August 11, 2011

Trigger Context to Provide Related Record Information

Developers who have worked with triggers may already know that related object information is not available in the context of a trigger. To elaborate on the problem, I'll give an example.

Take the Contact object. If I write a trigger on the Contact object, I'll have access to the AccountId value for each Contact handled by the trigger, but I will not have access to the related values such as Account.Name or Account.Owner.Name. Usually, to get around this, I would need to write SOQL within the trigger to retrieve the related values for use within the trigger.

This has personally been a great pain in my side, and it only seems to grow more intense as time goes by. Now, I'm stuck at trying to figure out how to get at those related values in another class that's used by the trigger. After some frustration, I came up with an idea.

What if I used a static variable stored in a utility class that I could set and get at will, wherever as long as I'm within the same trigger context? Well, that'd be pretty cool. To that end, I arrived at the concept for a TriggerContext class.

I won't spend too much time discussing it, as a demo's worth a million words. The classes and triggers inside TriggerContextDemo-1.0.zip can be added to any sandbox or developer org. To see the effects, simply create a new contact record, save it, and then update it by associating an account.

As I'm wrapping up this post, I realize that another, more straightforward approach to handling this could be to have the trigger's associated utility class automatically assign the related records back to the trigger records by writing to the sObject fields and not to the record ID fields. I'll look into this more tomorrow as I try to handle related values in a real project.

Tuesday, August 9, 2011

The Ingenuity of Person Accounts

As I meditated more on the idea in my previous post about people's connections to different accounts, a surprising realization occurred to me: We don't even have to engineer a new object; Salesforce has already done this for us! And the answer is... Person Accounts!

The basic implementation can be done in two simple steps:
  1. Activate the Person Accounts feature.
  2. Create Person_Account__c as a Lookup(Account) field on the Contact object

Conceptually, the idea is simple: The person is the core piece of the puzzle. Take John Doe, for example. John can be a contact for Acme Corporation and simultaneously be a contact for Zenith, Inc. All that's needed to represent these relationships are a person account record for John, two business account records for Acme and Zenith, and two contact records to link John to the two accounts.

Although I haven't thought this next idea in much more depth, I have an inkling that this model could potentially even replace the Nonprofit Starter Pack's Household object with a "Household Account" record type. Wouldn't that be a beautiful alignment of developer resources? All of Salesforce's main development efforts on Contacts and Accounts could then directly benefit all users in every industry. No more waiting for updates to the NPSP Householding package; just wait for the next seasonal release of Salesforce.

Friday, August 5, 2011

People, Not Contacts and Affiliations, Are the Way to Go

Poking around the nonprofit space today, I came across the Affiliations for the Nonprofit Starter Pack app on the AppExchange. I installed it, and all it ended up doing was creating a new object called Affiliation that links contacts with accounts. Ugh... I sense a very unpleasant asymmetry here, where a contact record can be related to an account either directly through the Account field or through an affiliation record sandwiched between the contact and another account.

While this structure definitely works to get us through most of our work, is this really the right way forward? If people at the Saleforce Foundation are pouring time and energy into developing something for the greater good, wouldn't it be great if we are assured that their focus is on the right vision?

Regarding affiliations, I don't think the Affiliation object is the right vision.

Here's a thought: Contacts were originally defined as people of interest related to an organization. Somehow, we diverged from this model by redefining contacts as people with a primary connection to a specific organization via the Lookup(Account) field. What's the difference, you ask? The difference is that in the original definition, a Contact record is the link between a person and an account; in the world with Affiliation as a junction between Contact and Account, we've redefined a Contact as the person, which it was never meant to be.

So, by introducing the Affiliation object, we've bastardized the idea of a "contact". How do we pick which Contact record stays with its account? How do we choose between a creating new Contact record and creating an Affiliation record? Is it better to have my Contact record as a child of account A with an affiliation to account B, or the other way around?


The answer: For orgs that want to map out people's relationships to different Account records, introduce the Person object. Then, link every Contact record to the appropriate Person record, and you have the magic sauce that paints the real picture of a person and his or her affiliations.

Monday, August 1, 2011

Removing ^M Characters from File with vi

So, I transferred a file from Windows to a Unix server, and when I opened the file with vi (not vim) on my server, I was confronted with endless ^M characters.

How do I get rid of these characters?

Basically, after some fumbling around on the internet, I determined that I needed to use the following command.

:1,$s/^M//g

To type the ^M character, press Ctrl+V for the ^ and then Ctrl+M to get the M afterward. vi apparently does not recognize the ranged specified by %, so I had to use 1,$ instead.