Monday, May 18, 2015

Forecasting Quota and Risk of Salesforce Upgrade


Problem

This is a bit of old problem, but we had this custom Visualforce interface in our internal org that allows you to mass insert and edit Forecast Quota.  This has been working fine for years, but when we tried to enter forecast for this year, we suddenly got this error:

Missing Required Field: [Quota Quantity]
However, when we tried to modify the code to allow manual entering of quota, we were getting error indicating that this field is not writable.


Solution

What turned out happen was that you need to have ForecastingType set if you are using ForecastingQuota inside of code after API v28.  Once we enabled a revenue forecast on opportunity (Setup > Customize > Forecasts > Setting), the interface worked again.

Takeaway

This was another lesson on using custom code with Salesforce (especially something that interacts with Standard feature, such as Standard object) and Salesforce upgrade.  Writing custom code can certainly improve the usability of Salesforce, and I do believe it to be one of major feature of Salesforce, but one has to be mindful that it can suddenly get broken without warning.  This is one of the reason why Salesforce recommends using as much of standard functionality as possible (70 to 80% standard functionality is the Salesforce benchmark).

Strange error when saving from Developer Console

This post is more of a reference for future if I encounter this error again, but I had a rather strange error when trying to save a modification to a Apex class from Developer Console:

Failed to create createContainerMember for containerId=undefined: null is not a valid containerId
After some googling, I had found following help article indicating that you need to create a new workspace when this error appears.  This did fix my error, but it doesn't really explain why this error appears.  If you have more in-depth explanation as to why this would happen, let me know.

Taking control of Custom Action in Salesforce1

I have been involved with a few projects that incorporated Visualforce pages into Salesforce1's custom action since the launch of Salesforce1, and one thing I had found annoying was that there was no documentation on how one can take over the action associated with "Submit" and "Cancel" button on top of the custom action page.



However, Salesforce has recently updated their documentations on how you can add your own action to these two buttons using Publisher SDK.  I first saw this on Visualforce Mobile Trailhead, but they have updated Salesforce1 Mobile App Developer Guide to include it as well.

To add your own Javascript action to the "Save" button, you would first include Publisher SDK:


<!-- Publisher SDK -->

<script type='text/javascript' src='/canvas/sdk/js/publisher.js'></script>

Then, you would modify following Javascript function inside your Visualforce page.

// When the panel is displayed, enable the submit button
Sfdc.canvas.publisher.subscribe({name: "publisher.showPanel", onData:function(e) {
    Sfdc.canvas.publisher.publish(
        {name: "publisher.setValidForSubmit", payload: "true"});
}});

// Action to be performed when submit button is pressed
Sfdc.canvas.publisher.subscribe({ name: "publisher.post", onData: function(e) {

    // ***************************************************
    // Add your own action here
    /* myOwnAction([params], 
          // Callback
          function(error, records) {
             if (error) {
               // Do something on error
             }
             else {
               // Close the window
               Sfdc.canvas.publisher.publish(
                { name: "publisher.close", payload:{refresh:"true"}});
             }
       }); */
}});

Tabs and Searching

As you gain more experience with Salesforce, you come to run into limits that make you think "why did they put that limit?"  One of such feature is searching custom object.  Over a year ago, we had a project with a customer who had quite a few custom objects in its org and had used up all their tabs.   One of the requirements for the project is to enable the search on a new custom object, but when we have set all the search layout, we weren't seeing the object in the search.  After some googling, we found out that you can search a custom object only if you have custom tab associated with it.  When we had contacted Salesforce support, we found out that you could purchase additional tabs just so that you can enable additional searching.  Also, you could implement your own Visualforce searching page, but I still find this to be rather strange limitation.

Saturday, March 28, 2015

History is in Detail! - Migrating Master-Detail Relationship with History Tracking on Child Object

Problem

Over the years as Force.com developer, I found that migration and trigger are two area where I encountered issues most frequently, and here is another interesting issue with migration in Salesforce.  I had a custom sObject that were in Master-Detail relationship with Account.  When I tried to migrate this object using Force.com Migration Tool, I was getting following error:

duplicate value found <unknown> duplicates value on record with id: <unknown> 
After much googling, I found this post on StackExchange, indicating that History Tracking might be a problem.  When I disabled the history tracking on the object, I was able to migrate the object.

Work-around
With the cause of the problem tracked down, I still found the prospect of manually enabling history tracking on the object and each field in the destination org quite troubling.  With Salesforce.com migration, some manual steps are unavoidable (e.g. Community setup, Quote enablement, etc.), but you do want to minimize the manual steps as much as possible, and I thought there might be a way to automate this step using Force.com Migration Tool.

First solution I considered was creating the object first with a lookup relationship with Account, then have another deployment of the same object with relationship change to Master-Detail relationship.  This did eliminate the "duplicate value..." error, but the problem was that when you change a relationship from Lookup to Master-detail (or vice-versa), it triggers sharing rule recalculation, which causes problem if you had any sharing rule being migrated at the later stage of the deployment step, which we did have for this project.

The eventual solution I came up with was a three-staged migration of the object.  First, I migrated a shell Metadata of the child object with Master-Detail Relationship on, but with history tracking turned off.  Second,  I migrated the shell Metadata file again, but with history tracking turned on.  Finally, I migrated the full retrieval of the child object Metadata.  One issue you have is that you have to manually maintain copies of shell Metadata files for these children objects, but schema for the shell is quite simple and you only have to create these shell files only once, whereas you have to perform manual step, which is prone to error, on every environment you migrate to.

I have checked in the code for the simplified version of this process in my github repository.  You can find it at https://github.com/jpaek/MasterDetailWithHistory.

Takeaway

The error message for this problem was rather misguiding for me, but this shouldn't come as a surprise to us Force.com developers, especially when working with migration.  Googling, as was case here, can help figure out what the problem is, but sometime you do have to manually figure out the problem by playing around with it, which can be quite cumbersome tasks.

Also, I want to point out that, with bit of thinking and experimentation, you can eliminate many of the manual steps involved with migration steps through Force.com Migration Tool.   

Monday, March 23, 2015

Task Trigger and Ugly Un-bulkfiication.

Problem

We had created a trigger on Case Task that would update a custom description field on the parent case with comment from the task when the status of the task changes to "closed."  This trigger worked at the beginning, but then this trigger started to fail with following error message:
Apex Task trigger cannot handle batch operations on recurring tasks.

It turns out that you cannot to have a trigger on event (including task) if you have any batch job on recurring events (see here) and that another team working with this client had implemented a batch apex job that managed recurring tasks related to some other object.  

Work-around

There really wasn't a work-around for this issue.  What we ended up doing was getting rid of the trigger and let user manually copy the value.

Takeaway

Trigger is one of the most problematic aspect of Salesforce.com development with many nuances, this being one of them.  With the release of the new Lightning Process Builder, we finally may have a work-around on this issue and many other trigger-related issues, although I cannot say that with high confidence as this very new feature with Salesforce.com.

Sunday, March 22, 2015

Mobile Design Template and Angular.JS

Problem

We had implemented a multi-step wizard for our client.  Two of the requirements for this wizard was that it needed to be mobile-friendly, and it needs to have bilingual support.  To meet this requirement I had tried to implement a mobile version of the wizard using Mobile Design Templates.   I had previously built a simple mobile-friendly Visualforce page using Mobile Design Templates and Underscore.JS following the Getting Started with Mobile Design Templates blog post from Salesforce.

Given the complexity of this application, I had used Angular.JS as the back-end.  However, I ran into trouble when I tried to incorporate the Mobile Design Templates' toggle input into this application.

We had this picklist field with two values that we want to render as a toggle input.  To do so I had the Angular.JS controller called the service that would grab the labels for those two values from Salesforce, in order to meet the bilingual requirement, and set those label as data-on-label and data-off-label.

(function() {

var app = angular.module('app', []);



 app.controller('InputCtrl', function InputCtrl(InputLabelService) {

        var inputScope = this;



        // Get the label of the input form from Salesforce
        InputLabelService.getFormValues().then(
            function(picklists) {
                inputScope. inputLabels = picklists. inputLabels;


               // This renders the toggle input
               $(document).trigger('onTemplateReady');
        });
    });
})();



<section class="border-bottom">
    <div class="content">
    <h3>Input</h3>
        <div class="form-control-group">
            <div class="form-control form-control-toggle" data-on-label="{{inputLabels[0]}}" data-off-label="{{inputLabels[1]}}">
                <input type="checkbox" name="toggle">
             </div>
         </div>
     </div>
 </section>
The problem was that Mobile Design Templates render data-on-label and data-off-label on the toggle input upon the call to 'onTemplateReady' Javascript trigger.  However, because how the two-way binding of Angular.JS is done, the rendering of the toggle input is done before Angular.JS can set the data-on-label and data-off-label with appropriate values, which ended up rendering the toggle input without any label.

Solution

The way I had gotten around this issue was by putting a $watch listener on the inputLabels and to trigger 'onTemplateReady' when it has a new value.

(function() {

var app = angular.module('app', []);



 app.controller('InputCtrl', function InputCtrl(InputLabelService) {

        // Get the label of the input form from Salesforce
        InputLabelService.getFormValues().then(
            function(picklists) {
                $scope.inputLabels = picklists.inputLabels;



                $scope.$watch('inputLabels', function(newVal, oldVal) {



                    if (newVal) {

                       // This renders the toggle input
                       $(document).trigger('onTemplateReady');
                   }
               });
        });
    });
})();




Takeaway

In the end, I actually ended up not using Mobile Design Templates as the tabbed navigation, which I had used in one of the page, didn't work in iPhone.  Instead, I ended up using Bootstrap along with Angular.JS.  I still think Mobile Design Templates is a good tool to have in your tool belt if you are building a very simple mobile application on Salesforce1; however, for any application with a moderate complexity, I would definitely look at alternative, such as Bootstrap I have used for this project or Ionic Framework.

Way in the @future - Problem of using Salesforce as Real-time Relay System

Problem

For one of the project I was on, we had following as one of the requirements.  In this requirement, the System 1 would send a record to Salesforce, which would store the record, transform it based on the data stored in Salesforce and transmit the transformed record to System 2.  The whole process from System 1 to System 2 need to take less than 5 minute to complete.

Originally, we had implemented a trigger on the creation of the original record - Record A - that would transform it and send the transformation - Record A" - to System 2 by calling a web service through a future method.

This has been working as expected for quite sometime.  However, the production org was on NA14, and when the NA14 performance degradation occurred last year, we were witnessing that this request was taking more than half hours, and sometimes more than several hours.

Our investigation revealed that the problem was that the request to the future method gets stuck in the Apex Job Queue due to the degradation issue.  We had investigated both the batch apex and outbound-message workflow, but the problem was that both batch Apex and outbound-message jobs are queued the same way as the future method was.


Workaround

The way we addressed this problem was by implementing a custom web service.  This web service stored the Record A into Salesforce as well as transform the record the same way the trigger was doing.  We had proposed two solutions on how to transmit the transformed record to system 2.  One was for the custom web service make a callout; the second was to return the transformed record to System 1 as the response to the web service call, and System 1 would transmit it to System 2.  Our test revealed that both methods eliminated the queueing issue; however, the client went with the second option given the importance of this process.

Takeaway

The takeaway for me was that Salesforce really isn't a ideal tool for implementing a real-time processing of data, especially if you are using one of asynchronous methods (@future method, batch apex, etc.) as Salesforce do not provide any SLA on the timeliness of these processes.

Sunday, January 18, 2015

Curious Case of Disappearing ID

Problem

Last week, I was deploying some changes to the recently deployed Apex classes into the production, but somehow it was failing on previously migrated test classes that were not related to the changes being deployed. To confirm that it had something to do with production environment, rather than the new code, I ran those pre-existing test classes in the production environment, and they were indeed failing even without the changes (I also had them run in Sandbox and confirm that they passed).  My initial suspicion was that someone had added something like a validation rule on the sObjects for which I was generating test data.  Although it was related to the test records being generated, the problem, it turned out, was not related to the validation rule, but something rather more strange.

The test classes had a structure similar to the following where I had a static method to generate test data for all the test methods and a test method that queries for the test data.
@isTest private class TestCustomController {   static void createBackground() {     List<Account> testAccts = new List<Account> {       new Account(Name = 'Test Account 1'),       new Account(Name = 'Test Account 2')};     Database.insert(testAccts);
    List<Account_Child__c> children = new List<Account_Child__c> {       new Account_Child__c(Name = 'Child 1', Account__c = testAccts[0].id)};    Database.insert(children);   }
  static testMethod void manipulateCustomController() {     TestCustomController.createBackground();
    Account queriedAcct = [SELECT Id FROM Account WHERE Name = 'Test Account 1'];
    // Initialize custom controller, pass on the account ID,     //and call method to query for the children of the accounts.   } }
To debug the problem in the production, I had put breakpoints in the createBackground() method after the insertion of the account and in the manipulateCustomController() method after query for the account through Developer Console and ran this test class.  What I found out was that the ID of the Test Account 1 in the createBackground() didn't match the ID in the manipulateCustomController()!

Workaround

I tried moving the code in the createBackground() method into the manipulateCustomController() method, and that did resulted in the ID being consistent through out the run of that test method.  However, this did not completely solve the test failure as I had another weird issue where the symbol table not showing some properties of an in-memory instance of a sObject, while it showed in the heap.

Takeaway

This does demonstrate that there are major differences in the internal implementation of the Test and "Production" environments of the Salesforce, mainly that the Test environment is somewhat unstable and has weird kink in it.  Also, it does demonstrate how valuable breakpoints can be when debugging problem in the Production org. 

Thursday, January 1, 2015

Incrementing Instance Variable of Virtual Class

Problem

I had following piece of code that increments the instance variable in the parent class within the for-loop of the child class:

public virtual class ParentClass {
  public Integer mapIndex{get; set;}
}
public class ClassWithError extends ParentClass {
  


  public ClassWithError {
    Integer mapSize;
    ...
    for (mapIndex = 0; mapIndex < mapSize; mapIndex++) {
      ...
    }
    ... 
  }
  ...

}
which resulted in following error:
Unknown error: virtual class data member of the parent in for-loop

Solution

The fix is to simply create a temporary variable to do the increment and assign the value of the temporary variable to the instance variable inside the for-loop:

public virtual class ParentClass {
  public Integer mapIndex{get; set;}
}
public class ClassWithError extends ParentClass {
  


  public ClassWithError {
    Integer mapSize;
    ...
    mapIndex = 0;
    for (Integer tempIndex = 0; tempIndex < mapSize; tempIndex ++) {
      mapIndex = tempIndex;
      ...
    }
    ... 
  }
  ...

}

Do Not Expect - Trouble with HTTP


This is a bit of old issue, but I making this post as it does drive home an important lesson regarding Salesforce.com custom code development.  For one of our customer, there was this legacy code that used HTTP Callouts, which has been working for several years.  However, around the time of Winter '14 Release, the users started reporting that that piece of code was not working.

After digging through it, I was able to narrow it down the problem to following error on response from the callout to the external web service - a standard non-descriptive error message that appears for pretty much all error with HTTP callout:
Read Timeout Error
Unexpected End of Element...

Because the way Apex parses the response,  I couldn't find out much more from the debug log.  As a next step, I tried to find out if the issue was related to how Apex handles the Callout or if it was something wrong with the web service itself by duplicating the request that the Apex code is suppose to generate within SoapUI.  However, from SoapUI, we were getting the response that we expect to get, leading us to go back to the Salesforce side of things.

This time around, what I did to find the issue in the Callout was to strip down the Callout message to bare bones to see if it would work and then adding the elements back to the message one at a time.  The bare bone message did indeed work from Salesforce, and it turned out that problem was caused by following header:
Expect: 100-Continue

The fix for this problem was simply removing that header.  I don't know for sure if this issue was introduced with Winter '14 Release or through the changes to the external web service (btw, this limitation is now documented here).  However, this does provide a reminder on the dangers of using custom code in terms of its fragility when it comes to upgrade either to Salesforce or external service it interfaces.

Wednesday, December 31, 2014

Introducing Lightning Components - Salesforce Front-end Framework: First Thoughts and Gotchas


One of the biggest announcements from Dreamforce '15 was the new Lightning user interface. For us developers, the part that would be of most interest to us is Lightning Framework – the new component-based Javascript Front-end web framework for Salesforce.com. From going through the Developer's Guide for the Lightning Components, here are my first thoughts and some gotchas I found.

The Lightning Components is intended to allow developing responsive-design single-page app.  This should allow the developers to develop not only a Salesforce app that is more responsive than with Visualforce, but it should also allow us build one app that would optimize based on the client, instead of building separate app for Desktop and Mobile devices.

In terms of the structure, I found it to be quite similar MV*-based front-end frameworks such as AngularJS, Backbone.js or Ionic Framework, and if you are familiar with any of those frameworks, you shouldn't have much difficulty with it. The basic structure is that you create an app, which consists of one or more components with each component representing a section of the page. Each component then can have its own stylesheet, controller/helper scripts, and events.

Some of the main benefits I see is that because it is based on the Javascript, it should make it easier to implement custom Javascript components, such as auto-complete input box.  If you have had experience of taking over the input field with custom code in Visualforce page, you know how nightmarish of task it can become, dealing with Visualforce-specific convention regarding IDs and trying to resolve conflict between Visualforce tag and your Javascript code. Also, the UI testing and testing automation should be easier with this framework as you don't have to deal with auto-generated mark-ups from compiled Visualforce code and aforementioned ID conventions.  I would also like to mention Live Preview support in regards to testing, which you can open from Developer Console.  Finally, this will make managing your CSS stylesheet much easier as you have a separate CSS file associated with each component, instead of having to deal with either static resources or embedded CSS.

As for drawbacks, I did find a few potential issues.  One such issue may be that you have to customize the look-and-feel of every component with your own stylesheet.  One advantage of Visualforce is that it gives you a consistent look-and-feel to the Salesforce platform by default, which is lost with custom stylesheet.  Another issue I found was the file structure.  With the component-based structure, it appears to have completely different file-system structure to the rest of the Apex and Visualforce code directory structure we are familiar with.  As far as I know, you can only edit Lightning Components code from Developer Console, but I would assume it will become available in Force.com IDE and Mavensmate, and I wonder how those IDE/editros will be able to handle this rather diverging structure.

Finally, I would like to close this post with some gotchas I found while going through the Developer's Guide:

  •  You can’t use Force.com Canvas apps in Salesforce1 if you enable Lightning components.
    •  I think this may be the biggest issue for people looking into enabling Lightning components.
  • In order to use Lightning Components, you need to register separate namespace for it.
  • Some HTML tags are not supported with Lightning Components.
    • Please see https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ref_supported_html_tags.htm for the list of the supported components.
  • You need to create a custom tab in order to enable your component in the Salesforce1 Navigation menu.  
    • Also, accessing your Lightning Component from the full Salesforce site is not supported - another major issue that I would think would be resolved before going into GA.

Saturday, October 11, 2014

A Developer's Guide to Dreamforce

Another Dreamforce is upon us, and, although I won't be attending this year, I thought this is an opportune time to discuss how to use your time while at Dreamforce based on my experience from last year.

The first advice I would give to any developer attending Dreamforce for the first time would be don't try to attend all the sessions.  Rather, I would minimize the time spend on attending sessions, but try to maximize your time at the Developer Zone.  At the Developer Zone, you will have a chance to get some hands-on experience with new products and emerging technologies.  If it is anything like last year, you will also be able to drop in and listen to a number sessions that are held at the open spaces, and you can, of course, participate on the mini hackathons, even if you are not in the $1 million main hackathon.

As for the actual sessions, I would focus on attend sessions that are presented by either a developer from Salesforce or developers well-known within the community.  Googling the presenters prior to attending sessions could help you decide whether you would want to attend the given session.  I would avoid any session that is specific to a product or a panel discussion as I found most of those were more of promotional rather than educational.  One exception to this is the open developer Q&A session at the end of the conference.  Some of the sessions that I found to be on the better presented include:

  • Testing and Testability
  • Javascript Debugging
Another fun aspect of Dreamforce is the numerous After-party.  These are great opportunities to social and get some great free food and drinks.  However, it's pretty exclusive, so try to do some research and sign up for those as soon as possible.


Finally, if this is your first time in the Bay area, I would take the weekend and do some sightseeing.  I heard the tour to Alcatraz and Segway tour are really fun, although I didn't get to do those last year.  Also, renting bike and crossing the Golden Gate bridge is great as well.

Anyway,   if this your first time at Dreamforce, I'm sure you will have a great time, and you'll learn thing or two about Salesforce as well.

Monday, August 4, 2014

Validation, Approval Process and Testing

Two of the common sources of headache for Salesforce developer is approval process and validation.  Because these are declarative aspect of Salesforce (i.e. configured through the Salesforce user interface) with some restriction, these can be difficult to manager and migrate

With it being now migratable, many of the pain points for developing approval process in the sandbox has been removed.  However, once you activate an approval process, Salesforce removes some of the functionalities.  You can find more about these limitations here, but I found the following to be particularly difficult to deal with when you have changes in business logic and need to modify the approval process:

  • You cannot delete active approval process, and you can't deactivate an approval process if there is any records that are submitted for approval (you have to hard delete those records).
  • Once you activate an approval process, you can't add, delete or change the orders of the approval step even if you deactivate them.



With the validation rule, the difficulty I sometimes encounter is when trying to migrate some code and there is additional validation rule in the destination org (e.g. production or QA sandbox).  These validation rule can cause your test methods to fail in the destination org even though it has passed in the development org.  You can either create those validation rule in your development org and refactor your test methods to meet the validation rule, or if you are confident that the additional validation rule will not cause the business logic error when the new code is deployed, you can temporarily disable to the validation rule in the destination org during the migration and re-activate it afterwards. 


Friday, November 15, 2013

New Course on Salesforce App Development on Udacity

While browsing courses on Udacity, I noticed that it will be offering new course on Salesforce App development starting on Monday.  It is aptly named Introduction to Salesforce App Development.  The full course experience is $105/month, but you can follow the courseware for free.  It might be of interesting course for those aspiring Salesforce developers.

Thursday, September 19, 2013

Upcoming Salesforce Webinars for Oct. 2013 - Migration, Notification, Mobile, and More

The October, 2013 lineup for the Salesforce webinars has been released, the details for which you can find in the Salesforce event calendar, as per usual.  For this month, instead of focusing on a single theme, the webinars cover various topics ranging from migration, to notification, to mobile development, and to Apex development.

The first webinar for October, which will be held at 7:00am and 10:00am PDT on October 2nd, is entitled Salesforce API Series: Release Management with the Metadata API.  Based on the description and technologies mentioned, the focus of this webinar will be on continuous integration.  This is not something we had to deal with, but for those looking to automate their release of process, this would be interest to you.

On October 10th (9:30am PDT), there will be another session of CodeTalk.  This time, it will be on Apex programming, so the Apex developers out there, get your questions ready.

On October 16th (7:00am and 10:00am PDT), there will be a second webinar, entitiled Alert! Event Notification Options for Force.com Apps.  This webinar promises to go over and discuss various event notification that are available through Salesforce.  The event notification is something that many of our customers ask for, so I am interesting to see if I can pick up some new techniques in this webinar.

Finally, on October 23rd (7:00am and 10:00am PDT) there will be another webinar on mobile development.  This one is called Intro to Salesforce Mobile SDK: Building Android Apps.  Based on the title, this will be similar to the last webinar on iOS app development webinar, except it will walk through development in Android app.  If you enjoy that last webinar and interested doing Force.com app development on Android platform, this would definitely be an interest to you.

Monday, September 2, 2013

Upcoming Salesforce Webinars for Sept. 2013 - Mobile, Mobile, and More Mobile

I am just getting back from my vacation, and for my first post-vacation post, I would like to let you know about upcoming Salesforce Webinars for September 2013.

One of the resources that Salesforce avail to the developers is the webinar - online tutorial or question and answer period - they hold frequently.  These webinars are usually held over GoTo Meeting or Google Hangout, and you can register for free on their respective webpages.  You can find out about their upcoming webinars on the Salesforce event calendar, but I'll also post somewhat regularly about the upcoming webinars here as well.

The focus for September seems to be on mobile development, probably in conjunction with release of version 2 of the Salesforce Mobile SDK.  The first of the webinar is entitled Intro to the Salesforce Mobile SDK: Building iOS Apps and appears to focus on iOS application development using Mobile SDK 2.0.  This will be held on Thursday, Septebmer 5, 2013 at 7:00am PDT and 10:00am PDT.

At 11:00am PDT of  Tuesday, September 10, 2013, there will be a webinar on Rapid Mobile Application Development Using the Appery.io Mobile Pack and Salesforce.com.   I am not familiar with Appery.io, but based on name and on description, this is another framework for developing mobile web application.  I believe this webinar will actually be run by the representative from Appery.io, so we should be able to pick up a thing or two on integrating this framework with Salesforce.

Finally, there will be another CodeTalk on Mobile development at 9:30am PDT, Thursday, September 12, 2013.  CodeTalk is an online question-and-answer session on a chosen topic that Salesforce hold somewhat regularly, and the topic is usually is closely tied to a recently-held webinar.  I usually find these CodeTalks more helpful than the webinar as webinar seems to be more geared towards the beginning developer whereas these are actually answering the questions the developers have.  One thing I would advise is to get your questions ready as it can go by pretty quickly.

Saturday, July 27, 2013

#viewAllDiscoTopics

The topic of this post probably is somewhat out of date, and it is unlikely that you will be encountering this same issue in the future.  However, I do believe it does warrant a post for a number of reasons.  First, because of the ridiculousness of the name and the absurdity of the error, #viewAllDiscoTopics has become something of standing joke for all the idiosyncrasies in Salesforce at my work.  Second, it demonstrates the perils of deploying migration during the Salesforce upgrade period, as I will demonstrate.  And Third and last, it demonstrates the pitfalls of Force.com Migration Tool, something that I will likely return to it over again and again in this blog.

Having outlined what we have learn from this bug, so what is #viewAllDiscoTopics?  Earlier this year,  just about the time when Spring '13 upgrade was being rolled out, we were trying to migrate from a pre-existing dev Sandbox to a newly-created testing Sandbox org using Force.com Migration Tool.  However, when we try to deploy the retrieval into testing Sandbox, we received following, and rather cryptic, error message:
Unknown user permission: ViewAllDiscoTopics
After some Googling, I found out that this was one of the permission that was removed from Spring '13 release of Salesforce.  As both the source and the destination orgs were Sandbox, and appears to have been upgraded, you would expect that either this permission should not have been included when the package was retrieved from the source org or should have been ignored by destination org when we were deploying it.  However, as many of us who have used Force.com Migration Tool know, Force.com Migration Tool is something of all-or-nothing proposition where you have very limited control on what can be retrieved.

Given that one of the reasons Salesforce.com recommends the use of Force.com Migration Tool, one would expect that there must have been some automated process to remove this user permission from retrieved XML metadata file.  Hence, I had opened a case and posted a question on Salesforce.com forum here.  However, only answer I had received was to manually remove that tag from the XML file, as you can see from that discussion.

My Work-around
For our migration process, manually removing this tag every time we migrate just was not acceptable to us.  Hence, I had written a small Python script with xml.etree.ElementTree to automatically remove any occurrence of userPermission tag whose child name node has viewAllDiscoTopics as its inner HTML value.  I won't post the source code here as this is something that is simple to implement and could be implemented with pretty much any modern scripting language.  However, I will post how I have set up my ant script to call to automatically call this removal script after retrieval as I suspect many of us are not familiar with it as Makefile.

As a first step to automate the tag removal, I added following ant target to call my Python script:
<target name="removeTags">
  <exec executable="python">
    <arg value="removeViewAllDiscoTopics.py" />
  </exec>
</target>
After that, I modified my custom target to automate the retrieval and deployment to call this target prior to deploying the retrieval to destination org:

<target name="deployAll">
  <antcall target="retrieve" />
  <antcall target="removeTags" />
  <antcall target="deploy" />
</target>

Take-away
Now, this does address the problem automating removal of this particular bug.  However, this does not address the underlying problem that you need to be aware of presence of such bugs and you have to create scripts to remove all occurrences of such bugs, which is clear limitation of the tool.  Also, using a custom script to massage the retrieved XML is something that I had to do to address other limitations of Force.com Migration Tool, and I will revisit this solution in future posts.  Finally, this is something that occurred precisely because the deployment happen during the Salesforce upgrade window.  This is something that is mentioned in recent Force.com webinar on deploy: From Sandbox to Production: Demystifying Force.com Release Management Part 1.  The suggestion from Salesforce.com in that webinar is to avoid deployment during the upgrade window, which is not practical for many enterprises due to their business cycle and which exposes one of the major limitation of Salesforce.com.

Sunday, July 14, 2013

About this blog

As a Force.com Certified Developer with about a year of experience developing in Salesforce and over five years working in the industry as a developer, there are much to like about in doing development on Salesforce.com platform.  As a standardized platform, it does take care much of the UI design decision.  However you feel about the look-and-feel of Salesforce, this does make the lives of non-UX designers, like myself, easier.  Although I am not a huge fan of Salesforce having their custom programming languages and design of these languages, APEX, the programming language for Salesforce, and Visualforce, the mark-up language, are fairly easy to learn and they are making strong efforts to add features to these languages.  As well, you can see they are opening up more and more aspects of Salesforce, making it easier to interact with external system as well as build your custom solution on top of Salesforce platform.

However, one aspect that has been frustrated me is the lack of open forum to document the pitfalls and bugs in Salesforce platform.  The many discussion forums, both internal to Salesforce and external forums, such as StackOverflow, focuses on answering specific implementation questions.  Salesforce's Community forum does have Known Issue section; however, this only tracks some of the cases open against their support and that were deemed to be worthy to be documented publicly.  The problem with not having an open forum for such discussion is that it is difficult to identify whatever issue one is having is an isolated incidence or whether others are having similar issue and to have open discussion about work-around.

To this end, the purpose of this blog will be document the pitfalls and bugs in Salesforce platform found by this Force.com developer, so as to engage wider discussion on this issue, as well as to help others experiencing similar issue.  In addition to this, I will post about useful resources I find or upcoming Salesforce-related events that looks to be useful.  Finally, I might make some shameless plug on some of my works as well.

I hope those reading this blog find these posts useful in your Force.com Development work and encourage you to making Salesforce even better developer platform than it is.