Sunday, March 16, 2014

3 Ways to Tell What Version of Salesforce You're Using

Your out-of-the-box Salesforce experience is typically driven by two attributes: your Salesforce edition and the version (i.e., which release) of your org.

The edition (e.g., Enterprise Edition, Developer Edition) is readily identified by examining your browser's title bar or running a query: SELECT Id, Name, OrganizationType FROM Organization

But finding the version is a bit trickier, with no "official" method to reference. You can try one of the three methods below:
  • Switch to one of the standard, out-of-the-box apps (e.g., Sales), and look at the app logo

  • Create or edit a formula field, and look for the largest API version in the $Api object

  • Generate an Enterprise WSDL (Setup > Build > Develop > API) and look for the SOAP service endpoint location

You can convert the API version number into a release using the assumptions that Salesforce pushes three releases a year (Winter, Spring, Summer) and that each release corresponds to a new major version number. For example, we know that Winter '14 is API version 29.0. This means that 28.0 is Summer '13, and 30.0 will be Spring '14.

Thursday, March 13, 2014

Allowed User License Changes: Upgrades, Downgrades, Switches?

An infrequent but significant question that companies ask about Salesforce user licenses is: Can I switch from this license to that license? At the time of Winter '14, I could not find an official matrix of allowed user license changes. However, the question lingers, and I balked at the thought of manually trying to change user licenses to see what happens every time I needed an answer.

Using what I hope is a valid approach, I've compiled a matrix of allowed changes, using what licenses existed in my Winter '14 test org. I'm sharing the high-level summary of my approach in case anyone case to reproduce the same results.
  1. Create test profiles for every user license
  2. Run an Apex test to compile the results of every possible change among profiles
Below are the user licenses that were analyzed and included in these results:
  • Chatter External
  • Chatter Free
  • Chatter Only
  • Content Only
  • Customer Community
  • Customer Community Login
  • Customer Portal Manager Custom
  • Customer Portal Manager Standard
  • Force.com - One App
  • Gold Partner
  • High Volume Customer Portal
  • Knowledge Only
  • Partner Community
  • Partner Community Login
  • Salesforce
  • Salesforce Platform
  • Siteforce Only
  • Work.com Only
My wish is that anyone asking the same question can now refer back to this matrix for a quick answer. All feedback on the accuracy of the results will be greatly appreciated.

Friday, February 21, 2014

"Illegally" Reparenting Children in Master-Detail Relationship with Apex

If you have a Master-Detail field in Salesforce that's not reparentable, what do you think will happen if you use Apex to change the field value on a record? I had expected to see an exception thrown. But after a few hours of head-scratching, I discovered I was wrong.

If you try to change the value of a Master-Detail field that is not configured so that "child records can be reparented," you will not see an error. Salesforce will simply leave the existing value in place as if you never attempted to make the change in the first place.

The interesting implication here is that developers should write Apex tests to validate expected an Master-Detail configuration. Admins and developers can work together more reliably, if you explicitly write an Apex test that confirms whether a Master-Detail field can be reparented. This way, when an admin changes the field configuration and unintentionally breaks something, a red flag will be raised by the test method, pointing you clearly to the unexpected configuration change.

To see what happens if you reparent a child record when that's not "allowed", try this:
  1. Create a custom object labeled "Alias" (Alias__c), with the record name configured as a text field
  2. Create a Master-Detail field on Alias labeled "Account" (Account__c)
  3. Configure the Account field on Alias so that child records cannot be reparented to other parent records after they are created
  4. Create an AliasUtilTest class, as seen in this paste, with a test method to assert that changing the Account field on an alias is a futile effort
  5. Run the test method in AliasUtilTest

Monday, February 17, 2014

AJAX Toolkit 29.0 Home Page Component

For orgs trying to push the limits of the standard Home tab in Salesforce, using JavaScript is essential. However, trying to pull in the AJAX Toolkit is not as easy as adding a merge field to a new home page component, because merge fields don't work here. Fortunately, making an assumption about where the toolkit resides allows us to create a home page component that's equivalent to {!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}.

This 1-minute video shows you how to create the component and add it to your home page layout, using the sample code from "Home Page Component: AJAX Toolkit 29.0". The only real "trick" that's needed to make the component work is to extract the session ID cookie and pass it to the sforce object.

Now all of your home page components can be Ajax-enabled.

Monday, February 10, 2014

Recommended Usernames for Salesforce Communities

With the shift from Portals to Communities, salesforce.com delivered an attractive package of changes and improvements for a critical feature. However, one subtle change in Communities produced significant implications for Portals-to-Communities migrations and new Communities implementations: the username namespace.

What do you do with usernames that were once acceptable but can no longer be used? And how do you prevent future collisions with other companies and their communities, so that we all play nicely as multi-tenants in the Salesforce world?

In short, there are a few options you can adopt, depending on your use case and appetite for supporting customizations:
  • The domain-qualified username; or
  • The community-qualified username; or
  • A (domain-community-qualified) hybrid username using both of the above schemes, and probably the best option of the three

All naming conventions are described below, and in all options the optimal implementation requires that you create a custom login page.

Background


Every username has an interesting property: The username must be unique within a given namespace or context. For example, you and I can both use the username "superuser", if you register "superuser" with Twitter and I register "superuser" with Instagram. In this case, Twitter and Instagram represent two unconnected namespaces. But as soon as you try to register the same username with Instagram, you'll get an error telling you that the username is already taken (by me).

Salesforce used to have separate namespaces for every single portal. This means that I could log into my company's org as martyc@slalom.com and also log into a partner portal as martyc@slalom.com, even though the usernames were identical. The reason is that in the Portals age, Salesforce considered my company's org and the partner portal as distinct and separate where usernames were concerned.

But with Salesforce Communities, usernames are all of a sudden pooled together into redesigned namespaces. Partner Community usernames now exist in a namespace that is shared among all internal organizations and partner communities, even including salesforce.com's own Partner Portal. On the other side, the namespace for Customer Community usernames is unique for each org, but the namespace includes Partner Community and internal usernames within the same org.

Companies that want to create a consistent customer or partner experience should choose a naming convention that minimizes the likelihood of username collisions.

Edit: Customer Community usernames share a namespace with other Partner Community and internal usernames within an org, but not with other orgs. The post originally stated that Customer Community usernames were pooled together with Partner Community usernames and internal usernames across all orgs. Props to Andy Ognenoff for noting this inaccuracy!

Domain-Qualified Usernames


The domain-qualfiied username is a naming convention where a community user's username also contains that user's email domain. For example, John Smith is a Salesforce user at Acme Corporation, which has a partnership with the Zenith Group. Knowing that John's regular username is jsmith@acme.com (also his email), Zenith's admin sets John's partner community username to be jsmith.acme.com@zenith.com.

Effectively, the domain-qualified username contains the following elements, which can be joined and transformed as you wish. The example above shows a period between the partner's prefix and domain, with the parent company's domain coming last.
  • Customer/partner email prefix (e.g., jsmith)
  • Customer/partner email domain (e.g., acme.com)
  • Parent company's domain (e.g., zenith.com)

For best results, you should implement a custom login page that accepts the user's email as the username, transforming that email to the community username behind the scenes.



Sample Community Login URL What the User Enters Username Stored in Salesforce Sample Email
https://zenith.force.com/partner/login jsmith@acme.com jsmith.acme.com@zenith.com jsmith@acme.com
https://zenith.force.com/partner/login martyc@slalom.com martyc.slalom.com@zenith.com martyc@slalom.com

Community-Qualified Usernames


The community-qualified username is a naming convention where a community user's username contains an additional "subdomain" after the '@' symbol. For consistency and easy decision-making, you can adopt a community's URL path as the subdomain. For example, Jane Doe is a customer of two divisions within Gamma Corporation, and Jane is also a customer of the Delta Group. Jane logs in as "jdoe" to all three communities, even though Jane's true usernames for the three communities are:

  • jdoe@products.gamma.com
  • jdoe@services.gamma.com
  • jdoe@my.delta.com.

As you can see, the usernames only differ in what comes after the '@' symbol. In this case, they key components in the username are:

  • Unique prefix (e.g., jdoe), self-selected by the user or auto-assigned by the parent company
  • Unique community subdomain (e.g., services.gamma.com), which includes the parent company's primary domain

Again, for best results, you should implement a custom login page. This time the custom page should accept the unique prefix (that comes before the '@' symbol) as the username, and then add on the community subdomain behind the scenes.



Sample Community Login URL What the User Enters Username Stored in Salesforce Sample Email
https://gamma.force.com/products/login jdoe jdoe@products.gamma.com jane.doe@gmail.com
https://gamma.force.com/services/login jdoe jdoe@services.gamma.com jane.doe@gmail.com
https://delta.force.com/my/login jdoe jdoe@my.zenith.com jane.doe@gmail.com

Hybrid Usernames


The (domain-community-qualified) hybrid username is a naming convention that combines the elements of both the domain-qualified username and the community-qualified username. As a result, the hybrid username can provide the following benefits:

  • Intuitive username for the customer or partner. Customers and partners can log in using their emails.
  • Minimized risk of duplicate usernames, across all Salesforce orgs and communities

Inside an org, every community username contains:
* Customer/partner email prefix (e.g., jsmith)
* Customer/partner email domain (e.g., acme.com)
* Unique community subdomain (e.g., services.gamma.com), which includes the parent company's primary domain

Due to the complexity of the stored username, you must implement a custom login page to succeed with this option. The login page should accept the user's email as the username, again transforming that email to the community username behind the scenes.



Sample Community Login URL What the User Enters Username Stored in Salesforce Sample Email
https://zenith.force.com/partner/login jsmith@acme.com jsmith.acme.com@partner.zenith.com jsmith@acme.com
https://zenith.force.com/customer/login martyc@slalom.com martyc.slalom.com@customer.zenith.com martyc@slalom.com
https://gamma.force.com/products/login jane.doe@gmail.com jane.doe.gmail.com@products.gamma.com jane.doe@gmail.com

Other schemes?


If you have other user naming conventions or username schemes for Salesforce Communities, please share them in the comments below!

Friday, January 31, 2014

JS for Salesforce Home Page Component

While it's not possible to add a Visualforce page or component to the standard Salesforce home page, it is possible to inject straight HTML and JavaScript into the home page via an HTML Area component. Furthermore, you can use Salesforce's AJAX Toolkit to connect to the API, which opens up a world of dynamic possibilities for your Home tab.

There's only one trick to connecting to the API: You need the current user's session ID. Luckily, this information is stored in the sid cookie and can be retrieved and easily stored in the sforce.connection.sessionId property.


From here, you can use all of the tools in the AJAX Toolkit to bring your data to life on the Home tab.

Monday, January 27, 2014

Extending Chatter Profile with Custom Subtabs

Out of the box, Salesforce only gives users limited access to user information through the Chatter Profile page. There are two tabs: Feed, showing the Chatter feed, and Overview, giving a nice overview of additional Chatter relationships and the ability to edit ~1 dozen User fields. However, organizations that want to extend the Chatter Profile page will not find any button-click admin options in Setup.

Thankfully, custom Profile subtabs give those orgs an option to extend the Chatter Profile without having to completely re-engineer the entire page (which is not really feasible considering the Chatter feed and related components). What's required is some Visualforce magic to expose related information directly on the Chatter Profile page as subsequent tabs coming after "Feed" and "Overview".


To provide access to personal data without exposing that data to other users, Salesforce provides a thoughtful separation of different subtab use cases. Admins have the option of showing custom subtabs in one or more of four different contexts.
  • Profile (Others): When a user looks at someone else's profile in the internal Salesforce "community"
  • Profile (Self): When a user looks at his/her own profile in the internal Salesforce "community"
  • Profile in Communities (Others): When a user looks at someone else's profile in a customer or partner community
  • Profile in Communities (Self): When a user looks at his/her own profile in a customer or partner community

Without restrictions on what to extend, subtabs really give developers the ability to deliver any functionality desired within the constraints of Visualforce. And knowing that the profile user's Salesforce ID can be retrieved from the sfdc.userId URL parameter, developers can provide a fully personalized experience for the user.