Thursday, March 27, 2014

Analytic Snapshots-Business Analytics Salesforce

General Overview:

Analytical snapshots (Available in professional, Enterprise, Developer and Unlimited editions) in Salesforce help the users to produce historical trends in their data. The data is stored in a custom objects pushed by a snapshot scheduler.  The features of Analytic snapshots are

1.       Allows the users to build the historical trend of data.
2.       Sourced by tabular & summary reports.
3.       Data stored in custom object. So the data stored is secure from user tampering.
4.       The user can define mapping and scheduled runs.
There are several pros and cons in Analytical snapshots.

Pros:

·         Supports daily monthly and weekly trends.
·         Snapshots details or summary data from reports.
·         Protects data from deletion.
·         Control access for the custom objects through custom object permission

Cons:

·         2000 row limit per user.
·         Limits to # of user runs per day.

Typical use cases:

              If a customer service manager want to analyze the number of open cases on day to day basis . He/she can create an analytic snapshot and schedule it for a daily run. The snapshots are automatically pushed in to a user created custom object. From where historical trends will be analysed.

How to configure:
Please refer the links and a Salesforce Video webinar for your reference

·        Build a summary or a tabular report
·        Create a custom object with all the fields identical as the SFDC report.
·         Configure ananalytic snapshot  and map the fields.
·         Schedule the Analytic snapshot for daily weekly or monthly run.



External Blog links:

How to solve: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY: maximum trigger depth exceeded “S object” error?

(Wow that is the longest title I've ever given a blog! You searched on your error message and you found my post, right? Now, to the issue-at-hand.)
Trigger recursion is a big nightmare for the Salesforce developer. When a trigger with odd criteria (malformed?) fires; it subsequently starts auto firing and results in an exception error; something like:

CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Update_Opportunity_Calculation_fields: maximum trigger depth exceeded “S object”

In order to solve this we use the help of a static variable.  Create an apex class with static Boolean variables and add a check in the trigger for specified Boolean  value results.

Here's an example:

My business case is that I wish to renew a subscription on an Account. I want to automatically create a new Opportunity. In this scenario, I wish to create another Opportunity, say a related child Opportunity, when a master Opportunity is inserted. I've created a after insert trigger on Opportunity. When I insert a new record, it gets fired.

Look at the code:
trigger recurssiontest on opportunity(after insert) {
     for(opportunity opp:trigger.new){
       opportunity o = new opportunity();
       o.Name='xyz child';
       o.parentid__c=opp.id; //id of the parent
       insert o;
     } 
}
This code will return: error CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Update_Opportunity_Calculation_fields: maximum trigger depth exceeded “S object”

So what’s the work around ?

Create a apex class with global or public access specifier and call the apex class inside the trigger in an IF statement. This will check to see, if the static variables inside the apex class meets the specified conditions.

Like this:
public class stoprecurssion{
public static boolean flag=true;
public static boolean runonce(){
if(flag){
   flag=false;
  }
else {
   return flag;
  }
   return true;
 }
}
In the trigger, never forget to add the IF check, which is called from the instance of the above class.

It will look like this:
trigger recurssiontest on opportunity(after insert) {
     for(opportunity opp:trigger.new){
      if(stoprecurssion.runonce()){
       opportunity o= new opportunity();
       o.Name='xyz child';
       o.parentid__c=opp.id; //id of the parent
       insert o;
       }
     }
}
Writing our trigger in this manner, avoids recursive firing of triggers.