Total Pageviews

Tuesday, September 10, 2013

SFDC quick heals ( 18-15 SFDC ID , Activating inactive stage picklist value, etc...)

Every now and then we stumble  upon small nagging issues which we research and resolve but few years down the line re-encounter them and proceed to reinvent the wheel.
One such trifling issue is that of the nagging 15 digit vs 18 digit id of salesforce (record id).

In salesforce each record Id represents a unique record within an organisation. 
These ids are in two formats /type /version for every record Id in salesforce :
  1. 15 digit case-sensitive version which is referenced in the UI (Detail pages / reports)
  2. 18 digit case-insensitive version which is referenced through the API
What do these 15 digit and 18 digit ids stand for:-
The last 3 digits of the 18 digit ID are a checksum of the capitalizations of the first 15 characters, this ID length was created as a workaround to legacy systems which were not compatible with case-sensitive IDs.
The API accepts the 15 digit ID as input but will always return the 18 digit ID.

How to get the 18 digit id in the UI?
One may write code to decipher the 18 digit id from the 15 digit id but an easier way out is to generate the 18 digit counterpart in a formula field by use of caseinsensitiveid() function.

Activating inactive/ re-activating picklist values in "Stage" field of Opportunity 

Activating the inactive picklist values of "Stage" field in Opportunity is bit cumbersome. Let me explain with an example. Lets assume I have an active stage called "stage1". Several opportunities are still assigned to "stage1" and one has to delete (de-activate it). One now has a "stage1" that cannot be reactivated. If one wants to "re-activate" it, one has to create a new stage with the same percent and other properties as the inactive "stage1". Then, one would delete the inactive "stage1" and, during this process, system will ask/prompt user to replace any opportunities that are associated with "stage1" with another stage. At that time one has to select "stage2". Now the "stage1" is deleted and all the previous "stage1" opportunities are now aligned to  "stage2".

Now one has to recreate the "stage1" as an active stage. The final step is to delete "stage2" and when prompted replace it with "stage1". "Stage2" will be deleted and stage1 will now will be active again.

Friday, August 9, 2013

Data Migration (Legacy system to Salesforce) a dummy’s guide

Data is distinct pieces of information, usually formatted in a special way.  Data is the most critical asset of any organization. The criticality of data makes any activity involving data crucial and delicate. The same logic makes projects involving “Data Migration” sensitive and mandates the handling with utmost care.

As the title suggests we are going to focus on Data Migration involving Salesforce as a platform in general and in particular we are going to reflect on:-

·        What are the “n” questions one should ask before planning a data migration project?

·        How Legacy Data should be moved over to Salesforce?

·        What are the “n” numbers of things to be careful about?

·        What are the “n” things to checked in Salesforce before embarking over a data migration project? 

Questions one should ask oneself while kicking off a Data Migration Project?

1.       What is the nature of system from where data which is being brought in?
a.       Legacy system like some Orcale Database, etc.
b.       Some CRM like Sugar CRM, Net Suite etc?
              The answer to the above question gives you the following vital inputs:-
·    So there is legacy data coming from another system
·    This means that we might need to bring in information like:-
1.       Created Date, Created by information
2.       The above information in SFDC is called “Audit fields/ Information
3.       For adding information about audit fields create a case with salesforce
           Audit Fields
System fields, which are read only and store information like “created date”, “created by id” (reference to user), “last modified date” and “last modified by id” are referred to as audit fields.
Ideally Salesforce treats these fields as “read-only” and these fields are set by the system by default and cannot be modified by the user.
Though under special condition these (audit) fields can be set by special permission from Salesforce by creating a case with “Salesforce” to that effect. The permission to set audit fields is not unlimited and is revoked after some time, if you need that you should be able to set audit fields longer do create another request with Salesforce.

Also note objects like:-
·          Account Feed
·          AccountShare
·          AccountTag
Don’t have audit fields

2.       What is the nature of Data?
a.       Is there currency related data? If yes is that data in different/ multiple currencies? If the answer is yes? Then we need to get “Multi-currency” enabled in our Salesforce organization/ instance.
3.       What is the numbers of  “users” that need to be created? Or how many users have to be created? Lets say if “X” users have to be created are these necessary number of seats in the “Salesforce Instance”?
a.       The answer will decide how you will frame the strategy for carry outing the data load vis-à-vis assigning of information like
·    “Created By Id”
·    “Last modified by Id”
4.       Are there users from different Time Zones? If yes then one has to handle time related data accordingly
5.       In what format data will be provided to you?
6.       What is the minimum information you need for each object, to successfully load data? In technical terms I means what are the “Required Fields”?
7.       What are the “business rules” that have to be taken care of? For example if there are certain business rules implemented in the system by way of “Validation rules or Triggers” then how such situations will be handled? For example if you have a validation that “Date of Sale” cannot be less that today, then how will you handle loading of legacy data, which will be in past. Answer will be perhaps deactivating such validations rules or commenting a portion of trigger during data load.
8.       When you get the data extracts (say csv files) from legacy system check the columns having dates are they in correct format and value?
a.       Many times you will see date represented as numerical date value, if yes-appropriate date conversions need to be done in excel using formulas.
b.        Check if the date values in legacy system and in csv files are same?
9.       W.r.t. text fields check the data length because if you are using excel or csv to massage and manipulate data then text fields which get truncated during such instances its advisable to use: -
a.       A database for data massaging and manipulation
b.       Informatica for making data extractions and loading into database and Salesforce.
10.    Also w.r.t. Salesforce always remember in the user object there are certain felds like “Community Nickname”, “Username” , etc which are unique across the Salesforce platform so if legacy data is coming from Salesforce, data massaging will involve making these data values unique.
There are scores of questions which come to my mind, but lets park them for the next blog …

Keep watching this space for more on “Data Migration”

Saturday, January 19, 2013

Custom Settings revisited !!!

I remember nostalgically the first major technical document I penned. It was for a product/project I had worked on - and the comments of the reviewer were Ispita why do you use such flowery language ~ I guess the person was being generous~ what was implied was ~ Ispita keep it short and simple.
Such comments are always priceless - and act as sharpening stones.
Apart from the two S mentioned above I now add a third dimension - spicy. So anything I write essentially has the three S- Simple, Short , Spicy ( na na don't run your horses of imagination - spice essentially  means -  the action on peppering your textual creation with anecdotes and personal touch , don't you look for yellow journalism - u will get none).

That reminds me this is not about - "How to write in Queen's language?" this blog will talk briefly about  "Custom Settings" and in particular about those which fall in the category of List custom settings.

So what are Custom Settings?

Custom settings are just like custom objects which act as placeholders to hold information which may tied to:-
1) an organization
2) a profile
3) a specific user

This leads us to the obvious question if its similar to custom objects then why create another data structure with similar traits? What purpose does it serve?
In pure technical terms you can say - "All custom settings data is exposed in the application cache, which enables efficient access without the cost of repeated queries to the database."  In layman's language lesser use of select statements and faster code execution.
Also they act as custom application wide global variables ( These are the List custom settings).
Now coming to the type of Custom settings . There are two types of custom settings:
List Custom Settings
This is the set of data which is available to the whole organization and remains the same irrespective of the profile or user accessing it. Its the socialistic type of custom setting same for everyone across the organization.Also since its cached and does not require issuing of costly SOQL queries they don't add to your overall tally of SOQL queries issued and thus help you in not breaching the governor limits.
Hierarchy Custom Settings
But what if you need a set of data which should morph or return different info based on which category of people is accessing it or which user is accessing it? So now the custom setting is not socialistic and return information based upon the rights of the user accessing it- or information is returned keeping in view the hierarchy- those are called the "Hierarchy Custom setting".
Click on the picture below for enlarged view.

Now how to access this via code in apex.
General syntax :-

Map<string , CustomSettingName > Variable Name = CustomSettingName.getAll();   

Here w.r.t. above diagram the syntax will be:-

Map<string , AppSetting> CST = AppSetting.getAll();   
string  strURL1 = CST .get('URL').compartment1__c;    
string  strURL2 = CST .get('URL').compartment2__c;    
So strURL1 contains à   and  strURL2 contains à  

I know you will say custom settings are so easy - but believe me whenever I start using them I always tend to forget some of the steps and go about re-inventing the wheel - so this time I thought of writing the steps for future reference.