May 5, 2012

Merging Cases in Salesforce

Although very important and needed, salesforce.com does not currently have a built in merge case functionality. There are several options in the AppExchange and several open ideas that are gathering speed. However, I haven't seen anything from Salesforce that makes me thing that this is going to be available any time soon.

I recently needed to create a merge method that can take all related records of a duplicate case and merge them into a master case. The sample below is the main apex code - nothing complex but there is a lot of code because you are dealing with lots of objects.

Here are some important notes regarding this sample:
  • This code sample assumes that the dup case is not significant, just it's related records.
  • The ParentId for attachments, CaseComments and EmailMessage is creatable but not updateable, so it is not possible to change case association by changing this field. That means that you have to duplicate the records, which leads to some loss of context like the comment created date and with email attachments. This can be handled by adding some text/links to the new records, which I've done some in this sample, but not a lot of it.
  • You may need to drop the 'with sharing' for the class if any of the involved objects are set to private in sharing rules.


Apr 29, 2012

Using Dates in Dynamic SOQL

I often use dynamic SOQL. It's a very useful when trying to satisfy multiple scenarios in a single query, or when building a query from pieces you don't have until runtime. It gets a little hairy keeping the code clean with large queries, but if you use consistent formatting and indentation, the code ends up fairly readable.

When it comes to using dates in dynamic SOQL, you have to convert your dates and datetimes to strings with a very specific format. I can never remember that format and that area of the documentation is very light, so I always end up trying to find where I used it last or searching online. The problem with searching online is that there are several wrong examples high on the search ranks (at least when I search for it).

So, here is the correct syntax if you ever need to use dates in dynamic SOQL...
  • date: myDatetime.format('yyyy-MM-dd')
  • datetime: myDatetime.format('yyyy-MM-dd\'T\'hh:mm:ss\'Z\'')

Here is an example that uses both a date and datetime in a dynamic SOQL statement:
list<contact> c = Database.query('SELECT id FROM SomeObj__c WHERE SomeDatetime__c > ' +
myDatetime1.format('yyyy-MM-dd\'T\'hh:mm:ss\'Z\'') + 
' AND SomeDate__c < ' + 
myDatetime2.format('yyyy-MM-dd') + 
' LIMIT 10');

Apr 22, 2012

Handy Inline JavaScript and CSS Hover Popup for Salesforce Lists/Tables

I tried to use my handy CSS hover popup in a table that was included within a component that also included a partial page refresh action (using rerender). The popup was working fine when the page was initially rendered. However, as soon as a partial refresh event occurs, the component loses track of the CSS that is included in the main page (static resource). Not sure why that happens. I tried everything I could think of, but could not get the component to remember the stylesheets after the rerender.

So I decided to recreate the same functionality with javescript and inline CSS. That way I am not giving the component the opportunity to lose the stylesheet from the parent page. I simplified the code to be as compact as possible, and you don't need a static resource or adding the visualforce stylesheet tag to the hosting page. What makes this work is the onmouseover and onmouseout events in the link as well as the z-index style in the link and the div inline styles.


  
    
      {!c.Name}
    
A couple of final notes:
  • The div needs to follow the end outputlink without any white space because some browsers treat white space as elements on the page, which makes the javascript nextsibling not work.
  • If the popup detail does not have carriage returns or special formatting use the an outputtext inside the div like in the example below. If you want to preserve carriage returns, use the following inside the div instead: <pre>{!c.Description}</pre>

Apr 2, 2012

Cliff Notes From Peter Coffee's Phorum Presentation

I attended the cloud computing conference Phorum last week, and thought that it was very well organized and attended for a first time conference. My main goal in going was to hear Peter Coffee, VP & Head of Platform Research at salesforce.com, who presented in the morning, was part of a panel in the afternoon, and closed the conference with a panel featuring 3 demo pit companies. This was the first time I've seen Coffee talk, and I was not surprised that he was very well spoken, articulate, and charismatic (Salesforce execs definitely have a type...). He was also friendly and personable when we chatted during one of the breaks.

Coffee's presentation (available on slideshare) was titled "Clouds of Revolution - Reinventing the (social) Enterprise". The main takeaway was that evolution is not a good enough process and that companies must undergo a revolution - replacing their current technology/processes altogether instead of adding and patching existing ones. Coffee argued that innovation is continuing its hockey stick path so adding improvements to existing systems still puts you at a disadvantage. I think it is an interesting premiss that, in my opinion, has not been traditionally embraced by Salesforce. However, Salesforce's recent big acquisitions and it's new mobile strategy seem to support this idea.

When it comes to the cloud, Coffee says that it is a reality and that enterprises should jump in fast and embrace learning and change (revolution not evolution). He was less than impressed with private clouds. In his opinion the label "private cloud" is used by CIOs so they can get funding for modernizing their existing data centers.

Coffee thinks that the next revolution is the social enterprise (not surprising coming from a salesforce.com exec). He gives convincing examples of real world and hard to solve problems that are not likely to be solved by adding technology alone (evolution), but require connectivity as an effective solution (social revolution). He also argues that social is a reality that enterprises cannot ignore, and that proactively providing secure social enterprise eliminates the inevitability of uncontrolled social usage within the enterprise. He also makes the arguments that social makes expertise rise to the top where the traditional org chart didn't. However, Coffee also acknowledged the yet unsolved data overload problem of social tools by saying that empowered social employees are not necessarily more efficient, and that algorithms and visualization must be added to convert data to curated info.

When talking about security in the cloud, Coffee argues that the cloud is more secure than alternatives but regulators and customers don't understand that. He believes that cloud security issues are sometimes more related to regional regulation as opposed to an IT issue. He continued to say that European regulators are sometimes more focused on the physical location of data than the technology that secures it.

Coffee also thinks that whitelisting is a better approach to security than the more standard blacklisting. He provides the Salesforce AppExchange as an example, and says that companies that went through the process thought it was a great learning experience. I have to say that my experience in this area is very different - I feel that the learning opportunities in the AppExchange listing process are small and are drowned by the long and tedious overall experience.

I hope this is a good summary for those of you that missed the conference. Again, the conference definitely exceeded my expectations, and was supported by an excellent speakers and panelists . I'll certainly plan to go next year, especially if Coffee is scheduled to talk again!

Mar 15, 2012

Step By Step Guide To Salesforce AppExchange Listing

Developing and packaging Salesforce.com apps is not that complicated, if you already have experience with SFDC or know what to look for. However, starting a provider relationship with Salesforce and navigating through all the orgs, requests, cases, and account execs is a complex and confusing process. As a matter of fact, every time you go through that process, you have to re-learn the necessary steps, because you likely forgot some parts of it or found out that Salesforce changed some other parts. I am going through this process again now, so I decided to put together a step by step AppExchange listing guide that is applicable these days, that perhaps I can use again later.

One important note is that this guide does not include the steps required to sign-up to be an ISVForce partner because you are not required to be an ISVForce partner to publish an AppExchange app. ISVForce partners benefit from access to a license management org/app, as well as Trialforce, but are also required to share 15% of the app revenue with Salesforce. The process of becoming an ISVForce partner takes 8-10 weeks to complete, and can be initiated by contacting your regional ISVForce account exec or opening a case in your Partner Portal (step 2 below). Again, it is not necessary to be an ISVForce partner to publish an app in the AppExchange.

So here are the steps. I numbered each step because the order is fairly important - in most cases, you cannot move forward without completing the previous step.

1) Create a Dev Org

This is the org you use to develop your app and create the initial app packages. If you haven't done this already, you can get free developer editions here. I normally have several dev orgs, and use them for development, testing and packaging. Don't wait until you are done developing to continue the process - when your app is close to being done, you should start thinking about the next steps.

2) Become a Salesforce.com Partner

The Salesforce Partner Portal allows you, as SFDC states, to "join the Salesforce.com Partner Ecosystem". You can register to the Partner portal here. This is a very important step because virtually all future steps start in the Partner Portal, or from an org that was created using the Partner Portal.

3) Create Test Orgs

One of the benefits of being a Salesforce Partner is that you can create lots of test orgs that you can use to test the packages you created in the Dev Orgs from step 1 with different licenses and configuration options. This is a very important step, especially if you want Group and Professional users to use your app. From the Partner Portal, you can request orgs that include the following licenses: Enterprise, Platform, One-App, Professional, Group, and Non-Profit. To get a Test Org, you need to login to the Partner Portal (from step 2), click on the "Create a Test Org" button or link, select the edition you want to test with in the dropdown, and submit.

4) Create a Partner Dev Org

Partner Dev Orgs are beefier versions of regular dev orgs. You will use this org to store and package your production code (Managed - Released), and later create upgrades and push patches. Although you can use a regular org for this step, I prefer the bigger org that is available to you as a partner. To get a Partner Dev Org, you need to login to the Partner Portal (from step 2), click on the "Create a Test Org" button or link, select the "Partner Developer Edition" option in the Edition dropdown, and submit. Once you create your final managed released package, be sure to go test it again in the Test Orgs you created in step 3.

5) Create an AppExchange Provider Profile

By now you should have a Managed - Released package in your Partner Dev Org (step 4). You don't need to have your ready-for-primetime package yet, but you should be pretty close. Creating an AppExchange provider profile will allow you to list and publish your AppExchange App. To create your AppExchange profile, log into your Partner Dev Org and click on the link provided on the detail page of your latest package; then click on the Start Publishing button to create your AppExchange provider profile. When creating your profile, it is very important that you link the profile to the Partner Portal user you created in step 2. The user name and password for the AppExchange provider profile will be the same as your Partner Dev Org credentials from step 4.

6) Create an AppExchange App Listing

Once you have an AppExchange Provider Profile, you can go to the Publishing tab, where you can create a new listing. A new listing is always private until the app passes the security review. While private, your app has a link on the AppExchange (which you can send to potential users), but it is not listed publicly and does not show up in searches. In this step you need your marketing and messaging content to be ready - some of the fields are very specific (like max length of certain text, and exact image size for logos), so you will probably need to edit your private listing a few time before it is ready to be published.

7) Submit Your App for Review

To go live on the AppExchange (make your listing public), your app needs to pass a security review by Salesforce. To start that process, you need to go to your private listing and click on the Offering tab. In the "Your Uploaded Packages" section, select the latest version of your app in the dropdown and click the "Start Review" link in the packages table. Only Managed-Released packages show up in the dropdown, so make sure you already created one before you go through this step. Once you start the review process, a case is automatically added to the Partner Portal (step 2) and you will receive an email with further instructions. It takes 6-8 weeks to gather and submit test result, pay the $300 fee, and go through the process. There are lots of moving parts in this step, so I may put together another post just for this step later on so stay tuned.

8) Create Test Drive Org

The Test Drive Org, gives your users the ability to sample your app before they install it. If set up, the AppExchange listing includes a Test Drive link that logs the user into a preconfigured developer edition org as a read-only user. If users of your app need edit/create credentials to make the demo useful, you should probably skip this step. To set up a Test Drive, Go to the Offering tab in your app listing (from step 6). In the "Test Drive" section click on the "Create Test Drive" link to get started. You'll need to create appropriate demo data and configure your application once the org is created - note that the admin user name for the new org is user@.demo. When the test drive org is ready, go back to the "Test Drive" section on the Offering tab and add the org using the read-only user credentials (eval@.demo).

9) Create Lead Management Org

Salesforce allows you to manage your leads even if you are not an ISVForce partner. However, that means that you'll need to get a Salesforce org (and pay for licenses) to be able to manage the leads from the AppExchange. You can link any standard Salesforce Org (not dev org) that has web-to-lead enabled. In lieu of having the License Management Application that is available to ISVForce partners, you can add custom fields and objects to your org to help you manage licenses. You can link the AppExchange listing to your Salesforce org, go to the Leads tab in your app listing (from step 6), and click on the "Change Organization" link.

That's it. Once your security review process from step 7 is complete, you application will be public on the AppExchange!