Thursday, March 26, 2015

Leaving a Learning Trail

One of the most worrying aspect of an client engagement is what comes after the successful deployment.

In one of my previous role, I was asked out of the blue without any prior warning to deploy a large chain-set containing 19 objects, some close to 380 fields, with 9 interlinked-relationships. Along with that I was to cleanse the data from legacy systems that amounted to 6 digits of records. And all this without a proper plan (I was the one who was supposed to come up with a plan for this) and two days prior to my extended vacation for Diwali. And that too when my mom had promised to make my favourite sweets.

But even on that day, when I prepared the plan on the 14 hour train journey from Delhi to Pune and then successfully deploying the whole package after relishing on the sweets, I was not as worried as I always am when I am told to do a Train the Trainers session at the clients office.

It is always good to have a train the trainers session and a good company understands that. However when it comes to estimates for a proper train the trainers session presents with difficulty. First, if its an implementation to replace their existing system (or worst with no system in place and moving from the DREADED EXCEL Sheets) a week worth of training is never sufficient. Not to mention the Users knowledge of Salesforce in the first place is very less and then telling them about the brand new system that we have developed for their convenience.

The point is, the exercise is fruitless which worries me. At the end of the session the customer promises to hire a good admin or if they have an admin, he promises that he will get certified and ask others to get one too. Somewhere down the line, it fails, people get confused using the new system and get back to their DREADED EXCEL sheets. This problem happens with a lot of Foundation customers as well.

When Salesforce introduced Trailhead I rejoiced, finally, I had something that I could give my customers, end users, new admins that was cheap (free duh), effective and a fun way of learning Salesforce. All I had to do now is go to the train the trainer sessions and verify they have the necessary badges to show us.

The trailhead website is very neatly organized and is very easy to navigate. If you are new to Salesforce, you could start with the basics track. this trail leads through 6 steps of Introduction to the platform, Data Modelling, Data Security, Data management, Formula fields and UI customization.

Not only that but Salesforce has now released amazing trailhead modules from programming track too. There are two programming tracks one for visual app development and another for Programmatic app development. 

The visual app development track consists in tutorials for process automation, Salesforce 1 basics, Setting up Chatter and how to handle change.


Share:

Friday, March 20, 2015

Code-pattern for Creating Mind-blowing Tabular Reports on Visualforce (With Sample code)

Salesforce.com has a mind-blowing reporting structure but it limits on data that is available on the system. Can we report on Data that is not present in the system?
For e.g., in a time-sheet management system, can we identify the people who have not filled time-sheets for a particular day? Can we report on data that is not present in the system? Can we identify records that are not created?

There is one thing I have learned working on Force.com platform for last 7 years, there is No No answer in Salesforce. Think a little bit and the answer will reach you. It is somewhat like climbing mount Everest, can you do it? Sure yes, in how many days depends on how fit I am (or how crazy I am)

Ok that Everest thing came up because someone did ask me that a few weeks back, moving on. Someone did also ask me about creating a report on missing details and I gave it a thought. The short answer is Yes we can, the long answer is we write a Visualforce page, anyone can tell you that. But what I really wanted to do was create a reusable code that I could use for a generic tabular report component.

The code is fairly simple, the pseudo code for the code is.
1. Generate a set of String for Rows
2. Generate a set of String for Columns
3. Prepare a map with Key as Row+Column and store the data accordingly.
4. Create a Dynamic table on Visualforce.

Apex Class for the page

public with sharing class TabularReportController {
    
    public Set rows{get;set;}
    public Set Cols {get;set;}
    public Map dataMap {get;set;}

 public TabularReportController(){
  prepareDataForReport();
 }

  public string getURLParam(String paramName){
            return ApexPages.currentPage().getParameters().get(paramName);
 }
 
 //Get the data for the rows
 public Map getrow(){
     return new Map([Select id, name, Accountid from Contact]);
 }
 
 
 //Get the data for the columns
 public Map getColumns(){
       return new Map([Select id, name from Account]);
 }


    //This is where the magic happens
 public void prepareDataForReport(){
     rows= new Set();
     cols= new Set();
     dataMap= new Map();
     Map columnsData=getColumns();
     Map rowData= getRow();
     
     //Geronimo
     for(Account a: columnsData.values()){
         cols.add(a.name);
         for(Contact c: rowData.values()){
             rows.add(c.name);
             String key= a.name+c.name; //Key is the key in which we set the data that we want to display.
                //Do some hazy logic here. This is where the key lies, you perfom your calculations and simply prepare the data
                //For display
                //For this example I am going to check if Contact is related to account
                if(c.accountid==a.id){
                    dataMap.put(key,'Related');
                }else{
                    dataMap.put(key,'Unrelated');
                }
         }
     }
     
 }
}

Visualforce page for the code


 <apex:page controller="TabularReportController" sidebar="false">  
 <style type="text/css">  
      .Related {  
            background-color: #0B610B;  
            color: #FBF8EF !important;  
      }  
      .Unrelated{  
            background-color: #A4A4A4;  
      }  
   </style>  
 <apex:sectionHeader title="Documents" subtitle="Report"/>  
 <apex:form >  
 <apex:pageBlock id="TheTable" title="Are the Accounts and Contact related?">  
 <table border="0" cellpadding="2" cellspacing="2" style="table-layout:auto" class="list">  
      <colgroup span="2"></colgroup>   
      <thead class="">  
      <tr class=" headerRow">  
           <th class=" headerRow" scope="col" colspan="1">Contact</th>            
           <apex:repeat value="{!rows}" var="row">  
           <th class=" headerRow">{!row}</th>  
      </apex:repeat>  
      </tr>  
 </thead>  
  <tbody >  
 <apex:repeat value="{!cols}" var="col">  
 <tr class="dataRow">  
      <td class="dataCell" colspan="1" style="white-space:nowrap"><span>{!col}</span></td>  
      <apex:repeat value="{!rows}" var="row" >  
&lt;!-- This is the Key, so to speak, for the entire page. Generating the key on the visualforce page --&gt;
      <apex:variable var="key" value="{!col}{!row}"/>  
      <td class="{!dataMap[key]}">{!dataMap[key]}</td>       
 </apex:repeat>  
 </tr>  
 </apex:repeat>  
 </tbody>  
 </table>  
 </apex:pageBlock>  
 </apex:form>  
 </apex:page>  

You can see the output of the report here

You can enhance the code using the same structure. Here are couple different thing I tried
  1. Adding a link to the data using wrapper
  2. Model window editing for the data
  3. Adding complex many to many relationships
  4. Plotting records that are not present

The list can go on.
Share: