Tuesday 14 October 2014

Difference between renderAs, rendered and reRender


1. RenderAs :
it is used with page component with name of any supported content converter. Currently only PDF is the only supported content converter.

example: below code will give output in pdf form


<apex:page standardController="Account" renderAs="pdf">

    <apex:pageBlock title="welcome {!$User.FirstName}, ">
        <apex:pageBlockSection columns="1" title="here is your Account Detail :">
            <apex:outputField value="{!account.Name}"/>
            <apex:outputField value="{!account.AccountNumber}"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>






















2. Rendered :
it use to show or hide visualforce elements. It is bound Boolean value in controller which can be true or false making visualforce component display or hide. If not specified its value defaults to true.

example:

<apex:page controller="renderedController" sidebar="false" showHeader="false"                                                                                                                 action="{!accountDetail}">
    <apex:form >
        <apex:commandButton value="Show Button" action="{!showButtonMethod}"/>        
        <apex:pageBlock title="Hi {!$User.FirstName} {!$User.LastName} " id="pageBlock1"                                                                                                      rendered="{!showButton}">
            
            <apex:pageBlockSection title="Here is Account Details">
                <apex:outputField value="{!account.Name}"/>
                <apex:outputField value="{!account.AccountNumber}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>


public class renderedController {

    public Boolean showButton { get; set; }
    public Account account { get; set; }
    public Id accId { get; set; }
    public renderedController() {
        account = new Account();
        showButton = false;
    }
    
    public void accountDetail() {
        accId = ApexPages.CurrentPage().getParameters().get('id');
        if(accId == null) {
            apexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Url Malformed'));
        } else {
        account = [Select Id, Name, AccountNumber From Account Where Id =: accId];
        }
        return ;
    }
    
    public void showButtonMethod() {
        if(accId == null) {
            showButton = false;
            apexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Url Malformed'));
        } else {
            showButton = true;
        }
    }
}



3. Rerender
Rerender is used to refresh one or more component. It contains the single Id of the component or list of IDs separated by comma.

example:

<apex:page controller="reRenderController" sidebar="false" showHeader="false"                                                                                                                        action="{!pageMethod}">
    <apex:form >
        <apex:commandButton value="Display Block" rerender="pageBlock1"                                                                                                                                action="{!accountDetail}"/>
        <apex:pageBlock id="pageBlock1">
        <apex:pageMessages />
            <apex:pageBlockSection >
                <apex:outputField value="{!account.Name}"/>
                <apex:outputField value="{!account.AccountNumber}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>


public with sharing class reRenderController {
    public Account account{ get; set; }
    public String accId { get; set; }
    
    public void pageMethod() {
        account = new Account();
        accId = ApexPages.CurrentPage().getParameters().get('id');
        if(accId == null)
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'No AccountId'));
    }
    
    public void accountDetail() {
        try {
            account = [Select Id, Name, AccountNumber From Account Where Id =: accId];
        } catch(Exception e) {
            system.debug(' **** ' + e.getMessage());
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, e.getMessage()));
        }
    }

}


Thursday 9 October 2014

What is My Salesforce Edition


Have you ever came across a situation where you need to know what is your Salesforce Org edition. If yes what you have done ? 

There are few easy ways to find out Salesforce edition.

1. From your web browser's Salesforce tab

Hover mouse over your salesforce tab in your web browser


 
 
 
 
 
 
 
in above snapshot text appears as "salesforce.com - Developer Edition "
 










when lands on Account tab text changes to
"Accounts: Home ~ salesforce.com - Developer Edition "

but the edition name always mentioned at last "Developer Edition",
It will work for other edition as well.
 
 
2. Second way to find out the edition is by clicking  SETUP > ADMINISTER
 








Hope this will help

Filter Records by Running User


Sometimes we want to see the records created by different User in Org and to achieve this we always create many custom list views having filter criteria "Owner Last Name " or "Owner First Name " which is fine if you few users but what will you do if number of users are large. You surely not going to create list view.

This limitation can be overcome by creating few formula fields and a list view.

Scenario:- 
Wanted to see the list of Account assigned to a particular Users.

1. To achieve this create one formula field [ Name = 'Formula Owner ' ]of type Number and decimal set to 0, and in formula editor write

IF( Owner.Id = $User.Id, 1, NULL) 

    Owner.Id represents Id of Owner of account
    $User.Id represent/give the Id os logged in User

and save the formula field.












2. Now to go Accounts and creates a new List view, where filter criteria would be 

Formula Owner = 1













set Visibility to "Visible to all users (Includes partner and customer portal users) "

3. Now see the list of record assigned to different Owner by logging in with different User
























Also see the Formula field value when seen as System Admin / another User who have access to that Account record and as Logged user who is the Owner of that Account record.


when owner and logged in user are different










when owner and logged in user are same










You can do similar type of customization for all the field which are related to Users or I would say have lookup on User i.e. CreatedBy, LastModifiedBy

Using colon in Report Name


While naming the reports we can separate the name to display on 2 separate lines. Its not been documented anywhere from Salesforce. I came to know about it from Scott Hemmeter

While naming the report separate the name with colon which will make reports to appear on two separate lines.

example :
if you name your report as "Developer Org Dummy Account Report " it will appear as











 and if you name your report as "Developer Org : Dummy Account Report  " it will appear as
 








Wednesday 8 October 2014

Salesforce.com Unique Field Limitation

 

Salesforce have some of the limitation and one of it is number of unique fields per object. Salesforce only allow 7 fields as ExternalId per object and also consider Unique fields as ExternalId.

If you already have 7 fields which are marked as ExternalId or UniqueId or both then you will receive an error if you try to create a new field as Unique/External

















 








and you try to make field unique it will show an error if that field in more than one record contains same value.









only Email, Text, Number fields can be marked Unique

Tuesday 7 October 2014

Set Parameter in Test Class


While writing test classes we often stuck with some parameters which need to be set to test the logic further, some developers try to avoid those parameters with Test.isRunning() in there logic which is not a good practice.

Salesforce powers us to set those parameter in Test Class. Suppose I am passing an Id of an Account in my url and on basis of Id I am querying Account.

public with sharing class ParameterController {
  
    private Id accId;
    public Account accDetail{get;set;}
    public ParameterController() {
        accId = ApexPages.CurrentPage().getParameters().get('Id');
    }
  
    public void accountDetails() {
        system.debug('  Account Id ' + accId);
        accDetail = [Select Id, Name, AnnualRevenue From Account Where Id =: accId];
        if(accDetail == null) {
            system.debug(' Some Logic');
        } else {
            system.debug(' Some Logic');
        }
    }

}


When I tried to write Test Class If I don't set the Id I will get an null point exception but to avoid the exception and to test my Class I can set the Id or any parameter as below

@isTest
public class ParameterController_Test {
    static Account testAccount() {
        Account newAccount = new Account();
        newAccount.Name = 'Test Account';
        newAccount.AnnualRevenue = 100;
        return newAccount;
    }
   
    static testMethod void accountDetails_Test(){

        Account newAccount = ParameterController_Test.testAccount();
        insert newAccount;
        PageReference ref = Page.Your_Page_Name;

        Test.setCurrentPage(ref);

        ApexPages.currentPage().getParameters().put('Id', newAccount.Id);

        ParameterController controller = new ParameterController();

        controller.accountDetails();
    }
}



Set the Parameters as

PageReference ref = Page.Your_Page_Name;

Test.setCurrentPage(ref);  

ApexPages.currentPage().getParameters().put('Id', newAccount.Id);  


Also refer ApexPages Method : click here

Saturday 4 October 2014

DML Options


We can use DML options while inserting or updating by setting desired options in Database.DMLOptions object. We can set options either by calling Databse.DMLOptions "SetOptions "method or by passing it as parameter to Database.insert or Database.Update methods.

Database.DMLOptions have following property

1. allowFieldTruncation : From Apex version 15 and higher if any field value is too large error message generated and operation gets failed. Using allowFieldTruncation we can truncate the string.

Syntax: Database.DMLOptions dml = new Database.DMLOptions();
          dml.allowFieldTruncation = true;


2. assignmentRuleHeader : Allow us to specifies if assignment rule to be used while creating Lead or Case

with assignmentRuleHeader we can set following options
    a. useDefaultRule : Indicates whether default (active) assignment rule to be used for Lead or Case.
    b. assignmentRuleId : Id of assignment rule for Lead or Case. 

 NOTE: For the Case sObject, the assignmentRuleID DML option can be set only from the API and is ignored when set from Apex. For example, you can set the assignmentRuleID for an active or inactive rule from the executeanonymous() API call, but not from the Developer Console. This doesn’t apply to leads—the assignmentRuleID DML option can be set for leads from both Apex and the API.


Syntax: Database.DMLOptions dmo = new Database.DMLOptions();
          dmo.assignmentRuleHeader.useDefaultRule = true;

          Lead newLead = new Lead(Company = 'Lead Corp', lastName ='Smith ');
          newLead.setOptions(dmo);
          insert newLead;


3. emailHeaderThe Salesforce user interface allows you to specify whether or not to send an email when the following events occur:
  • Creation of a new case or task
  • Creation of a case comment
  • Conversion of a case email to a contact
  • New user email notification
  • Lead queue email notification
  • Password reset
Using emailHeader property you can set

a. triggerAutoResponseEmail : Indicate whether to trigger auto response rules for Leads and Cases.

b. triggerOtherEmail : Indicate whether to trigger email outside the organisation.

c. triggerUserEmail : Indicate whether to trigger email that is sent to users in organisation


Syntax: Account newAccount = new Account(Name = 'Test Account');
insert newAccount ;
             
Contact newContact = new Contact(email ='puneetmishrasfdc@gmail.com', firstName='test', lastName='Lead', accountId = newAccount.Id);

Database.DMLOptions dmo = new Database.DMLOptions();
dmo.emailHeader.triggerAutoResponseEmail = true;

Case newCase = new Case(subject = ' Salesforce Limit ', contactId = newContact.Id);
insert newcase;

4. localeOptions : The localeOptions property specifies the language of any labels that are returned by Apex.

5. optAllorNone : The optAllOrNone property specifies whether the operation allows for partial success. If optAllOrNone is set to true, all changes are rolled back if any record causes errors. The default for this property is false and successfully processed records are committed while records with errors aren't. 

Creating Parent and Child Records in Single Statement


Inserting Parent and Child record in single statement is commonly asked question in Interviews. This could be achieved using external ID fields instead of inserting parent record then querying its ID and then inserting Child record.

Let take an example, I want to insert Account and Contact records in single insert DML statement.
To do so I will first create Contact Object and populates some of its fields, then creates two Account objects. First account is only for foreign key relationship and other for account creation. Both account have ExternalId field. Then we will call database.insert by passing it an array of sObjects. First element in array will be parent sObject and second element will be child sObject.

// Child record
Contact newContact = new Contact(FirstName = 'Child', LastName = 'Contact', Email = 'puneetmishrasfdc@gmail.com'  );

// Creating reference Account
Account accountRef = new Account(ExternalId__c = 'Vr123Cloud');
newContact.Account = accountRef ;

// Creating parent Account which will get inserted
Account parentAccount = new Account(Name = 'Parent Account', ExternalId__c = 'Vr123Cloud');

//below statement will create an Account and Contact
Database.SaveResult[] = database.insert(new sObject[] { parentAccount, newContact });


Account and Contact records gets inserted with relationship successfully and only 1 DML statement is used for above process.

We have used Datebase method to insert the parent and child records, we can also used simple DML insert statement to do same.


Account acc = new Account(Name = 'Parent Account', ExternalId__c = 'Vr123Cloud');

Contact cont = new Contact(FirstName = 'Child ', LastName = 'Contact ',  Account = new Account(ExternalId__c = 'Vr123Cloud'));

insert new List<sObject>{acc, cont};

Friday 3 October 2014

Apex DML Statements



Apex allow us to perform Data Manipulation Language (DML) operations to insert, update, merge, delete, and restore data in a database.
Following DML Statements are available

1. Insert : 
Insert DML operation adds one or more sObjects records to our organisation.

Syntax: insert sObject[ ]

2. Update :
Update DML operation modifies one or more existing sObject records in our organisation's data 

Syntax : update sObject[ ]

3. Upsert :
Upsert DML operation creates new sObject records and updates the existing sObject records within single statement, externalId can be used with upsert Statement.

Syntax : upsert sObject[ ]  extenal_Id

external_Id should be used to identify the record that already exist in organisation's data. 

NOTE : if custom field declared as externalId does not have unique attribute selected, the context user must have "View All" object level permission for the target object or the "View All Data" permission so that upsert does not accidently insert a duplicate record.


Upsert uses the sObject record's primary key (or the external ID, if specified) to determine whether it should create a new object record or update an existing one:
  • If the key is not matched, then a new object record is created.
  • If the key is matched once, then the existing object record is updated.
  • If the key is matched multiple times, then an error is generated and the object record is neither inserted or updated.


4. Delete :
Delete DML statement deletes the one or more existing sObject records from organisation's data.

Syntax : delete sObject[ ] 

5. Undelete :
Undelete statement restore one or more sObject records from the organisation Recycle bin.

Syntax : undelete sObject[];

6. Merge :
Merge statement can merge upto 3 records of same sObject into one of the records, deleting others and re-parenting any related records.

Syntax : merge sObject sObject; 

The first parameter represents the master record into which the other records are to be merged. The second parameter represents the one or two other records that should be merged and then deleted. You can pass these other records into the merge statement as a single sObject record or ID, or as a list of two sObject records or IDs

merge sObject sObject[]

merge sObject ID

merge sObject ID[]


NOTE : According to Salesforce we can only merge Accounts, Contacts and leads

sObjects that cannot be used together in DML Options
DML operations on certain sObjects can’t be mixed with other sObjects in the same transaction. This is because some sObjects affect the user’s access to records in the organization. These types of sObjects must be inserted or updated in a different transaction to prevent operations from happening with incorrect access level permissions. 
Following are the objects which can not be used with other sObjects when performing DML operations in same transaction
1. FieldPermissions
2. Group 
3. GroupMember
4. Object Permission
5. PermissionSet
6. PermissionSetAssignment
7. QueueSObject
8. ObjectTerritory2AssignmentRule
9. ObjectTerritory2AssignmentRuleItem
10. RuleTerritory2Association
11. SetUpEntityAccess
12. Territory2
13. Territory2Model
14. UserTerritoryToAssociation
15. User


There are few Objects which do not support DML but can be accessible in queries
  • AccountTerritoryAssignmentRule
  • AccountTerritoryAssignmentRuleItem
  • ApexComponent
  • ApexPage
  • BusinessHours
  • BusinessProcess
  • CategoryNode
  • CurrencyType
  • DatedConversionRate
  • NetworkMember (allows update only)
  • ProcessInstance
  • Profile
  • RecordType
  • SelfServiceUser
  • StaticResource
  • UserAccountTeamMember
  • UserTerritory
  • WebLink

All these DML Statements comes with some Governor Limits 
Total number of DML Statements :                                                                                    150
Total number of records processed as a result of DML statementsApproval.process, or database.emptyRecycleBin                                          10,000

If suppose I have insert 5 record of Account, I can do that individually
Account acc1 = new Account();
Account acc2 = new Account();
Account acc3 = new Account();
Account acc4 = new Account();
Account acc5 = new Account();
insert acc1;
insert acc2;
insert acc3;
insert acc4;
insert acc5;
In above scenerio our 5 DML statements is been utilized which will cause an problem if I have to insert many records, our DML statement limit will reached easily for this.
To handle above problem we can use collection for insert or other DML  statements
List<Account> accountList = new List<Account>();
accountList.add(new Account(Name = 'Account A'));
accountList.add(new Account(Name = 'Account B'));
accountList.add(new Account(Name = 'Account C'));
insert accountList;

In above scenerio our only 1 DML statement is utilized. But if you want to take it even further we can do this with collection of sObjects, sObject is a base object in Apex ie every object can be cast into sObject which will allow us to create one list of different Objects.
List<sObject> allObject = new List<sObject>();
allObject.add(new Account());
allObject.add(new Account());
allObject.add(new Contact());
allObject.add(new Contact());
allObject.add(new Custom_Obj__c());
allObject.add(new Custom_Obj__c());
insert allObject;
using above method we are now able to execute insert different record of different objects in single DML statement.
We have now learnt how to conserve our governor Limits.