Wednesday, 22 October 2014

Custom Settings in Salesforce

Custom Settings in Salesforce


Description:

Custom settings to create and manage custom data at the organization, profile, and user levels. Custom settings data is stored in the application cache. It can access efficiently, without the cost of repeated queries. Custom settings data can be used by formula fields, Visualforce, Apex, and the Force.com Web Services API.

There are two types of custom settings:

List Custom Settings:

It have user-independent values, retrieved under multiple names.
  •          Setting for development environment.
  •          Setting for volume testing environment.
  •          Setting for production environment.
List custom settings need to be accessed using a controller if you want to availiable them on a page, for example return ListSetting__c.getInstance('Test1').Field__c;

Note: It can be stores static data that can be used in apex code.

Hierarchy Custom Settings:

It can be configured at varying user specificity levels under a single name;
  •          Setting per user.
  •          Setting per profile.
  •          Setting for whole org.
Hierarchy custom settings are easily retrieved in Visualforce: {!$Setup.Student__c.Field__c} and will be resolved according to the current user context.

Note: It Can be stores data that may change depending on user, profile or org wide default.

How to configure Custom Setting in salesforce:

Step1:Goto---->Setup---->Custom Setting--->Click on New Button---->To Create Custom Fields

    
                      



Step 2: Click New Button enter All Information

     
                       



Step 3:Click Manage Button to see all records particular object(StudentData__c) in custom setting.

                       


Example:

https://c.ap1.visual.force.com/apex/CustomSettingEx

Visualforce page name: CustomSettingEx

     
                   


Apex Class: CustomSettingMethod

                     



Output:

                      


Note:
Custom settings have their own instance methods to allow easy access.
It looks like

                        


Limits in Custom Settings:

1. The total amount of cached data allowed for your organization :
    i.  1 MB multiplied by the number of full-featured user licenses in your organization.
    ii. 10MB.
2. 300 fields per custom setting.
3. You can’t share a custom setting object or record.
4. Custom settings are a type of custom object.
5.Each custom setting counts against the total number of custom objects available for your organization.
Interview Question's on this topic:
  • What is Custom settings?
  • How Many Types of Custom Settings?
  • What are instance methods in custom settings?

Animated Apex Command Button For Ajax Request

Have you ever noticed the Salesforce "Quick Save" button?? The button actually gets disabled while the class or the page is being saved. Hey Isn't that cool? Well this is not anymore Salesforce secret!. We can implement this in any visualforce page very easily without any JavaScript and HTML. Here we go 



<apex:page >  
   <apex:form >  
     <apex:pageBlock title="Animated Ajax Button">  
       <apex:outputPanel layout="block" style="text-align:center">  
         <apex:actionStatus id="myStatus">  
           <apex:facet name="start">  
             <apex:outputPanel >  
               <apex:commandButton value="Saving..." style="width:120px" disabled="true"/>  
               <apex:image value="/img/loading24.gif"/>  
             </apex:outputPanel>  
           </apex:facet>  
           <apex:facet name="stop">  
             <apex:outputPanel >  
               <apex:commandButton value="Save" action="{!save}" style="width:120px" reRender="myStatus" status="myStatus"/>  
             </apex:outputPanel>  
           </apex:facet>  
         </apex:actionStatus>  
       </apex:outputPanel>  
     </apex:pageBlock>  
   </apex:form>  
 </apex:page>  

Difference between Custom Object And Custom Setting.

anuragsfdc.blogspot.in/2014/02/difference-betwwen-custom-object-and.html

Currency Formatting In Visualforce Page

Well few days ago while working with a Visualforce page I came across a requirement of showing currency field using proper currency formatting.


For Example


  • 6000 should appear as $6,000.00 in the vf page
After checking the standard Salesforce tags I was unable to find a solution. but somehow figured out that <apex:param> tag can be exploited here.
So do the currency formatting in a vf page you can use the below markup.
<apex:outputText value="${0, number, ###,###,###,##0.00}">  
      <apex:param value="{!Account.Amount__c}"/>  
 </apex:outputText>  
Hoping this helps for your currency formatting need!

Sunday, 12 October 2014

Edit and Delete Command For Your Datatable In Visualforce

Most often that not you need to show data to the users in form of a table, such as Salesforce List Views or Related Lists.

Visualforce allows us to easily implement such page with a few lines of code. However, most often you would want to be able to add more interactivity/functionality to your page by supporting Edit or Delete command or any other custom operation that is required by design.

Today's article will show you how you can get that working for you.


Above picture depicts how the final result will look like, very much like Salesforce.com standard pages, isn't it?.

In this example I list the first twenty Account records that Apex finds and show then on the screen and then I would like to have actions such as "Edit" that forwards the user to Account edit page and brings the user back to my page again after the modifications are done and also "Delete" action that receives a confirmation from user and removes an Account record from Salesforce CRM.

So let's talk about the User Interface (UI) components required first and then we will look into the controller's code to see how it all works together.

Steps to add the page tags:
  • I first add a PageBlock component and set the title to "Accounts"
  • Then I want to put a PageBlockDataTable in the my Visualforce page.
  • In this step I simply add all the data columns I want to show to the user and leave the first column empty for the next step.
  • Now we are ready to add the action items to the first column of the dataTable.
Below is the page tags that I have used to make it all happen:
<apex:page controller="DataTableEditRemoveController">
<apex:form id="form" >
<apex:pageBlock title="Accounts">
  <apex:pageMessages ></apex:pageMessages>
  <apex:pageBlockTable value="{!accs}" var="row">
     <apex:column >
       <apex:outputLink title="" value="/{!row.id}/e?retURL=/apex/{!$CurrentPage.Name}" style="font-weight:bold">Edit</apex:outputLink>&nbsp;|&nbsp;
       <a href="javascript:if (window.confirm('Are you sure?')) DeleteAccount('{!row.Id}');" style="font-weight:bold">Del</a>
     </apex:column>
     <apex:column value="{!row.Name}"/>
     <apex:column value="{!row.BillingStreet}"/>
     <apex:column value="{!row.BillingCity}"/>
     <apex:column value="{!row.BillingPostalCode}"/>
     <apex:column value="{!row.BillingCountry}"/>
  </apex:pageBlockTable>
</apex:pageBlock>

<apex:actionFunction action="{!DeleteAccount}" name="DeleteAccount" reRender="form" >
   <apex:param name="accountid" value="" assignTo="{!SelectedAccountId}"/>
</apex:actionFunction>
</apex:form>
</apex:page>
 
How It Is Done For Edit Action:
Since the standard Account edit page is good enough for me I used an outputLink component to link the record to its Standard Edit page. In Salesforce for standard objects you can follow this format to get the URL for their edit page: /{RecordId}/e

I also wanted this to work in such a way that would return the user back to my Visualforce page once the user clicks on "save" or "cancel" in the Account edit page. In order to do that I need to add the following to the URL: /{RecordId}/e?retURL={returnURL}

In the Page's source code (above) you see that for return URL I have used {!$CurrentPage.Name} merge field, where I could simply put my page name. I like writing code clean! By doing this if you later on decided to change your page name, you do not need to worry about breaking anything! You page will continue to work with no problems!

How It Is Done For Delete Action:
In order to support this action in your page you need to do a bit of coding. The key is to be able to find out which account was selected by the user to be deleted.

In this example I have used a actionFunction component that triggers a Controller's Apex method call "DeleteAccount".

Before getting more into the coding part I wanted this link to get a confirmation from the user about deleting the record before actually we remove it.
In order to do so, we need to use a little bit of Javascript "window.confirm", the javascript function returns true if the user clicks on OK and false if the user selects "Cancel".

In order to capture the user's selection as to which account should be deleted I have added a "param" tag to the actionFunction component which passes the Account ID to the controller and as soon as user clicks on the link.

Now let's take a look at the code:
public class DataTableEditRemoveController {

   public List<Account> accs { get; set; }
  
   //used to get a hold of the account record selected for deletion
   public string SelectedAccountId { get; set; }
  
   public DataTableEditRemoveController() {
       //load account data into our DataTable
       LoadData();
   }
  
   private void LoadData() {
       accs = [Select id, name, BillingStreet, BillingCity, BillingPostalCode, BillingCountry from Account limit 20];
   }
  
   public void DeleteAccount()
   {
      // if for any reason we are missing the reference 
      if (SelectedAccountId == null) {
      
         return;
      }
     
      // find the account record within the collection
      Account tobeDeleted = null;
      for(Account a : accs)
       if (a.Id == SelectedAccountId) {
          tobeDeleted = a;
          break;
       }
      
      //if account record found delete it
      if (tobeDeleted != null) {
       Delete tobeDeleted;
      }
     
      //refresh the data
      LoadData();
   }    
  
  
}
 
Funny thing is that in my tests if you do not set the "reRender" attribute of the "actionFunnction" component the param is not passed to the controller and the "SelectedAccountId" property is not populated. Go figure....

Also I really wanted to get it working with commandLink or commandButton components instead using actionFucntion and javascript, but was not so lucky!

Enjoy!
 
 

Thursday, 9 October 2014

Updating records with adding the user name


when ever user update the record that user name assign to the sales rep field.


Tigger updatesalesrep on account(before insert, before update){
   for(Account all : trigger.new){
     acc.ownerid = userinfo.getuserid();
     user user=[select name from user where id:= acc.ownerid ];
     acc.sales_rep__c = user.name;
  }
}

Wednesday, 1 October 2014

Hourly Apex Scheduler

Parameters for hourly execution (run in System Log):
String CRON_EXP = '0 0 * * * ?';
clsScheduledHourly sch = new clsScheduledHourly();
system.schedule('Hourly Sync', CRON_EXP, sch);
Class:
global class clsScheduledHourly implements Schedulable{
  global void execute(SchedulableContext ctx) {
    syncBatch();
  }
  
  public static void syncBatch() {
    List<AsyncApexJob> apexJobsList = new List<AsyncApexJob>(
      [Select TotalJobItems, Status, ApexClass.Name 
       From AsyncApexJob 
       where Status!='Completed' and Status!='Aborted' and ApexClass.Name='syncReportBchbl']
    );
    if(apexJobsList==null || apexJobsList.size()<=0) {
      syncReportBchbl rb = new syncReportBchbl();
      try {
        Database.executeBatch(rb, 5);
      } catch(System.LimitException e) {
        //do something
      }
    }
  }
Test:
  static testMethod void testExecute() {
    String CRON_EXP = '0 0 0 3 9 ? 2022';
    
    Test.startTest();
    // Schedule the test job
    String jobId = System.schedule('testBasicScheduledApex', CRON_EXP, new clsScheduledHourly());
    
    // Get the information from the CronTrigger API object
    CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
    
    // Verify the expressions are the same
    System.assertEquals(CRON_EXP, ct.CronExpression);
    
    // Verify the job has not run
    System.assertEquals(0, ct.TimesTriggered);
    
    // Verify the next time the job will run
    System.assertEquals('2022-09-03 00:00:00', String.valueOf(ct.NextFireTime));
    // Verifiy that it has not run
    Test.stopTest();
  }    
}

Using Ant to retrieve metadata of Salesforce components

I was using Eclipse to download the metadata for all reports, and then using a "Search all files" to run a search on the field's API name. But downloading the metadata is a really time-consuming process. Ant can accomplish the same thing in a matter of split seconds! 

Here's how to download all your Salesforce metadata (including emails, reports, dashboards, etc) using the Salesforce ant distribution package from Salesforce and java ant. (Note that I'm installing this on Windows 7) 

Installation
Step 1: Download Java JDK: http://www.oracle.com/technetwork/java/javase/downloads/index.html. Install anywhere.

IMPORTANT NOTE: JDK 7 caused a problem in my Eclipse IDE at work, but it was fine on my home computer. Just FYI.

Step 2: Download Ant: http://ant.apache.org/bindownload.cgi. Extract.

Step 3: Download the Salesforce ant distribution package from Salesforce: Setup | Develop | Tools, and then click Force.com Migration Tool. Extract. 

From the distribution zip file, copy ant-salesforce.jar into your Ant installation /lib/ directory.

Step 4: Set environment variables. Instructions here -- http://ant.apache.org/manual/install.html#setup 

(Windows 7) Here are the environment variables to set:
  1. Add both Java and Ant bin directory to your path -- no spaces in the path!
  2. Set the ANT_HOME environment variable to the directory where you installed Ant.
  3. Optionally, set the JAVA_HOME environment variable


To view or change environment variables:
  1. Right-click My Computer, and then click Properties.
  2. Click the "Advanced system settings" option.
  3. Click the "Advanced" tab
  4. Click Environment variables.

Step 5: Open command prompt as administrator (right-click, select "Run as administrator"). Test your installation by typing in "ant -version". You should see something like this:

Retrieve all Report folders
So if you look at the Metadata API documentation, you'll soon realize that you can do a grab * to retrieve all data for a particular component, such as ApexClass or CustomApplication. HOWEVER, you'll also realize that not all components are wildcard-able, including CustomObjects and Reports. You'll have to list all folders to retrieve the data under them. Therefore, since the goal of this tutorial is how to retrieve all metadata for reports, here's how to retrieve the list of all report folders.

Step 1: Create a new project in Eclipse with the login credentials of the salesforce environment that you wish to search. Finish that process.

Step 2: Once that's done, right-click on your project, select Force.com > "Add/Remove Metadata Components".

Step 3: Select all metadata checkboxes. Click the OK button.

Step 4: This step is very important! Click "Apply" but DO NOT DOWNLOAD CONTENTS! You can do this by clicking the "No" button on the next two popup windows that asks if you'd like to refresh your project and download additional contents.

Step 5: When that's done, right-click on your src folder, select "Properties", copy the Location.

Step 6: Open that location in your file explorer, copy the file "package.xml".


Retrieving Metadata
Back to our Ant installation. In our Salesforce ant installation directory, looking at build.xml, the target that we are interested in is "retrieveUnpackaged".

What I did was to make a copy of the "sample" directory to work with. This is important, because, as it turned out, there was an error in the Salesforce Metadata API documentation, and it helped to have a reliable source file to compare against. You may want to have a copy for each Salesforce environment that you're working with. But for the sake of this tutorial, I'll assume you're working right off the sample directory that came with the download.

Step 1: Copy package.xml into <salesforce ant directory>/sample/unpackaged/package.xml. You can create the directory if it's missing.

Step 2: Under <salesforce ant directory>/sample/, edit build.properties to insert your salesforce login credentials. Remember to insert your security token after the password if you're working outside of your Salesforce's IP range.

Step 3: In the same folder, there is a build.xml. Look for <target name="retrieveUnpackaged">. It should look like this:
<target name="retrieveUnpackaged">
  <mkdir dir="retrieveUnpackaged"/>
  <!-- Retrieve the contents into another directory -->
  <sf:retrieve username="${sf.username}" 
               password="${sf.password}" 
               serverurl="${sf.serverurl}" 
               retrieveTarget="retrieveUnpackaged" 
               unpackaged="unpackaged/package.xml"/>
</target>
Step 4: In command prompt, cd to <salesforce ant directory>/sample/ and run "ant retrieveUnpackaged".

Here's a screenshot of a successful retrieval:
Error: If you're getting this error, you may have to set the proxy in build.xml:
<project name="Sample usage of Salesforce Ant tasks" default="test" basedir="." xmlns:sf="antlib:com.salesforce">
    <property file="build.properties"/>
    <setproxy proxyhost="prxoy server URL" proxyport="port num"/>
    <property environment="env"/>
...


Source: 
jkraybill:
http://stackoverflow.com/questions/6793458/how-to-download-all-salesforce-com-report-metadata-for-extremely-large-orgs

Force.com Migration Tool Guide:
http://wiki.developerforce.com/index.php/Migration_Tool_Guide

Force.com Migration Tool Installation Guide:
http://www.salesforce.com/us/developer/docs/daas/index_Left.htm#StartTopic=Content/forcemigrationtool_install.htm

Force.com Metadata API Guide:
http://www.salesforce.com/us/developer/docs/api_meta/api_meta.pdf

Apache Ant Installation Guide:
http://ant.apache.org/manual/install.html#setup