Search

Saturday, 18 July 2015

Object Definition Capture

I launched my 2nd app last week, which is a free app; so Id like to take the opportunity in this newsletter to do a bit of self promotion. Hopefully my readers will like this free app.

I don't want to send you to sleep but I'd like to tell you a short story.

In every company Ive worked in so far Product Owners, Business Analysts etc often have different styles of capturing requirements and recording them. Unfortunately often is the case that  requirements are not captured accurately or completely. The net affect is that the developer or administrator does not produce what is expected and the tester is not sure of what to test. The developers and administrators have to have additional multiple meetings until the full requirements are captured completely and recorded, which results in a lot of wasted time.
This frequently occurs when capturing requirements for objects and fields, but this should be the easiest of all types of requirements to capture because the number of different permutations that could be captured in the requirements is actually finite, unlike that of a code related project.

So I decided to create an app that would solve 4 main issues when capturing requirements for Objects and Fields.


                                    Capture object and field requirements in a consistent way for all Product Owners, Business Analysts
                                    
                                   Save time for Product Owners and Business Analysts when capturing requirements
                                    
                                   Developers and testers are given a consistent approach and so requirements are easily understood

                                  Product Owners and Business Analysts accurately capture all relevant requirements


15 companies have already installed my app in just 4 days since it was launched.


You need to add your org to Remote Site Settings, so if your org is say https://na12.salesforce.com, you would add this URL to Remote Site Settings. The bold part is the part which will be different for your Salesforce org.

Another benefit that the app could provide for you is that it will find all the Report Types and Page Layouts that you have in your system and enter them into 2 Custom Objects. You may be able to use this data for other purposes.

I hope you find the app beneficial.


Structuring Salesforce Invocable Methods

Invocable Methods are an important addition to the platform and Ive been calling for a complete overhaul of the Salesforce workflow engine for a long time and finally Process Builder was introduced a couple of releases back. 

There a few issues and limitations of Invocable Methods however:

  1. Passing Sobject lists appears not to work and instead you have to pass Ids of the Sobjects and then perform a SOQL to get the Sobjects, so you have to be mindful of SOQL limits. I would expect Salesforce to fix this issue in future releases, so this might go away.


  1. Another limitation is that you can only have 1 Invocable Method per class, which means you can end up having many classes. There is a neat way to get around this however:

Lets consider 2 examples. One Invocable Method sends an email introducers customers to The Self Evolving Software app, the 2nd Invocable Method updates a field on the Account to make post codes correctly formatted. 


@InvocableMethod(label='Setup_Salesforce_To_Salesforce_Email' description='Sends a Email To Explain Setup Of Salesforce To Salesforce')
public static void sendBenefitsEmail(ID[] emls){
      Attachment[] att = [Select id,Body, Name From Attachment
      where name='SES Introduction.pdf'];
       
      UtilEmail.sendEmail(emls,'How To Use The Self Evolving Software App', att);        
}




 @InvocableMethod(label='Format postcode on Account' description='Format postcode on Account')
public static void formatPostcode(ID[] accs){
      Account[] acc = [Select BillingPostalCode From Account
      where Id In :accs];
      for (Account eachacc : acc){
            eachacc.BillingPostalCode =
            UtilFormats.postcodeFormatting(eachacc.BillingPostalCode);
      }

      update acc;
}








The issue here is that we would have to create 2 classes with 1 Invocable Method in each.

The solution is to combine all Invocable Methods into an InvocableMethodHandler class and call to separate classes where the actions will take place




We first need to create a wrapper class to hold our data

In the labels for each InvocableVariable you probably want to display something a bit shorter as this will appear in the process builder.

 public with sharing class KeyValueInv {
      @InvocableVariable(label='Optional key if you want to represent a collection' required= false)
      public String key;
      @InvocableVariable(label='Stores the value' required= true)
      public String value;
      @InvocableVariable(label='The data type of the value' required=true)
      public String fieldtype;
      @InvocableVariable(label='This identifies the function to call' required=true)
      public String type;
     
      public KeyValueInv(String thiskey, String thisvalue, String thisfieldtype, String thistype){
            this.key = thiskey;
            this.value = thisvalue;
            this.fieldtype = thisfieldtype;
            this.type = thistype.toUpperCase();
      }


}

Below is the only invocable class and method you will ever need to create as we can send to it any type of data to the KeyValueInv class, plus in the InvocableMethodHandler we identify the function to call

public with sharing class InvocableMethodHandler {
      @InvocableMethod(label='' description='')
      public static void processType(KeyValueInv[] kvLst){
            if (kvLst[0].type == 'Send Benefits Email'){
                  UtilClass.sendBenefitsEmail(kvLst);
            }
            else if (kvLst[0].type == 'Format Postcode'){
                  UtilClass.formatPostcode(kvLst);
            }
           
      }

}



 public static void sendBenefitsEmail(kvLst[] kvs){
    //code .....
 }


public static void formatPostcode(kvLst[] kvs){
    //code .....
}





Now when you create your process builder you will be able to set the 'Send Benefits Email' as or 'Format Postcode' and this will decide which function to ultimately to call.