Monday, 26 March 2018

Enable Domain for Lightning component Building

As few of my friends requested for lighting training ,I thought of writing this blog so that including my friends others will get help and comfortable in lighting component development .

To start lighting development we should have a salesforce organisation ,People does not have salesforce organisation can create a free developloper organisation by clicking the link below .Once you will click the link it will redirect  to fillup the form,after saving the form you will get an email. You need to click on the link to rest the password to get the organisation ready for lightning component buiding .

https://developer.salesforce.com/signup

To built a lightning component we should have below organisation setting ready .
1.We should enable domain first to start with .Follow below steps to registaer Domain .

Please follow below tril head link to enable domain :

https://trailhead.salesforce.com/en/projects/slds-lightning-components-workshop/steps/slds-lc-1

Once your domain name is enabled we will start creating first lighting component .





Thursday, 22 September 2016

Queueable Apex In Depth

The class which implements the Queueable Interface are basically called as Queueable apex class .
The interface has only one method execute which takes the parameter of QueableContext which has one method.

Below are the  classes and methods related to Queueable Apex

A.Queueable (Interface)
   1.public void execute(QueueableContext context)
B.QueableContext (Interface)
   2.public ID getJobId()

C.Limit(Class)
1.public static Integer getLimitQueueableJobs()
2public static Integer getQueueableJobs()

D.System(Class)

  1.public static Boolean isQueueable()
  2.public static ID enqueueJob(Object queueableObj)

Examples :

public class QueueableClass implements Queueable { 
    public void execute(QueueableContext context) {
        // TODO
    }

}


Queueable Apex Limits:

1.You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction. 
2.Limits.getQueueableJobs() helps to check how many queueable jobs have been added in one transaction
3.No limit is enforced on the depth of chained jobs, which means that you can chain one job to another job and repeat this. 
4.Can add only one job from an executing job with System.enqueueJob, means that only child job can exist for parent queueable job
5.For Developer Edition and Trial organizations, the maximum stack depth for chained jobs is 5 .


Friday, 19 August 2016

Integration/webservice Concepts

I saw people in industry are really crazy to learn Integration .Real thing is that integration is not a rocket science kind of thing .
In my view a developer who is logically good he will definitely good in integration .

Lets discuss about integration/web service .

Web service basically are of  two  types :
1.SOAP(Simple Object Access Protocol)

2.REST (Representational State Transfer) 

I know every body have  at least  idea about above two types of we service.

Again in each we can have Inbound and Outbound web service .

Lets discuss what is inbound and outbound web service . 

When we are writing a service for other and for us it is Inbound and for Other it is outbound web service .

Same way when we are consuming other's service then for us it is outbound and for them it is inbound web service .

I think now we are clear, what is inbound and out bound web service .

Lets discus as a sales force developer  how we can write inbound web service  for others .

Inbound Web Service Using SOAP :

Here we will learn how to write a sample web service using SOAP and how we can test ,also how we can write test class for this .


To write a web service we need to write a apex class . 


  • Class should be global access specified .
  • Methods should be start with web service key word .
  • Any method that uses the Web Service keyword should  static  .
  • Return type should not Map,Set,Pattern Object, Matcher Object,Exception Object . 
  •  We cannot deprecate webService methods or variables in managed package 
Example 1:

Assume that we have written a web service  to get account name based on one external Id .

So while calling this web service  client needs to pass theexternal Id and in response it will return the name ,we can return other things as per our requirement .

global class AccountService{
    webservice static String getAccountName(String extid){
       if(extid != null){
        String accName=[SELECT Id,Name FROM Account WHERE APINameExtid =: extid LIMIT 1].Name;
        return accName;
       }
       return null;
    }
}
Replace APINameExtid with your external id Api name of field  created in Account .

Example 2 : 




Wednesday, 30 December 2015

Before Insert Trigger

As discussed before we have clear idea about  trigger and context variable .Lets start before insert trigger .
 Basically trigger is the most important part in  project ,why because when ever we will do any DML the trigger will execute always .We can restrict execution of code inside but not the trigger .
Still trigger should always bulkified so that all data should mapped properly ,If data will wrong then there is no meaning of software development .To maintain data we should write proper trigger  code .

Trigger BeforeInsertTriggerDemo on Account(before insert ){
   for(Account acc :Trigger.new ){
     acc.Name='Before'+Name;

    }
}

Lets have some discussion on the above code .
Line number one which basically we can say syntax of trigger .or signature of trigger .
All trigger should start with Trigger key word next to the trigger is a Name of trigger . then on which object you need to write trigger that object name you need to add after on .
Name of the trigger should be a justified name which we can  give up to 255 character,

Object name you need to give the api name in which object you need to write trigger . 
Next to object name you need to add the event within the bracket .

Here I have added before insert, however we can add all seven event separated by comma .
 Next line is for loop ,why for loop we all developer knowingly or unknowingly writing this line .  
 As  Trigger.new is of type list which contains the list of manipulated records ,So we are implementing list iterator for loop in apex here .
Basically in case of  before insert   the record is not inserted in database .So we can assign any value to the fields  .
Second line the loop will iterate based on your record size .Suppose are going to insert 1000 account record then your loop will iterate 1000 times .

Now as per 3rd line each records name will prefixed by Before context .


We can add validation in trigger also .Observe  below trigger .Here I have added a validation that from a multiselect picklist you can only  select 2 values .

trigger MultiSelectPickListRestriction  on Account (before insert,before update ) {
  for (Account acc :Trigger.new ){
    if(acc.MultiPickList__c.split(';').size() >2 ){
        acc.addError('You can only select any two values');
    }
  }
}


Lets check what is not available in before insert context .
Basically in before insert context id and audit fields are not available .Why because the record is not yet inserted in database .So once record will save to data base then only those fields will available .

Some people says DML is not possible in before context .I think it is partially correct .Because DML is not possible in same object or record ,however if you have any relationship(Master Detail /Lookup ) fields then you can collect the id and do DML on those records .

One more thing which we have already discussed in before insert there is not concept of Map as Id is not there in before context .Also no old concepts as record is completely new .
 
I think before insert part is clear .we will discuss before update next very soon  enjoy  :)

 
 



Wednesday, 4 November 2015

apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute.

This is the basic problem in apex .So we can use html input file and java script to solve this type of issue .

Below code will help you avoid the issue .

Visual force Page
<apex:page id="pgid" controller="InputFileUsingHtmlJavaScript">
<apex:form id="frm">
<input type="file" id="fileId" name="attFile" /><br/>
<apex:actionFunction name="passToController" action="{!doAttachment}" reRender="frm">
<apex:param name="fname" value="" assignTo="{!filename}" />
<apex:param name="body" value="" assignTo="{!body}"/>
</apex:actionFunction>
<apex:commandButton value="Save" onclick="remoteLocationPost();" />
<script>
var blobfile;
function getAsText(readFile) {
var reader = new FileReader();
reader.readAsDataURL(readFile);
reader.onload = attLoaded;
}
function attLoaded(evt) {  
var fileString = evt.target.result;
blobfile = fileString;
var  input = document.getElementById("fileId");
var filename= input.value;          
passToController(filename,blobfile);
}
function remoteLocationPost(){
var fbody= document.getElementById("fileId").files[0];
getAsText(fbody); 
}   
</script>
</apex:form>
</apex:page>
Apex Class 
  public class InputFileUsingHtmlJavaScript{
    public String filename{get;set;}
    public String body{get;set;}
    public void doAttachment(){ 
        Attachment at=new Attachment();
at.Name=filename;
at.Body=Blob.valueOf(body);
at.Parentid=//Needs to add your record id below which you need attachment ;
Insert at;
   }
}



Wednesday, 21 October 2015

Export All fields with Field Label API Name and DataType of an Selected Sobject


Below code will  help you to select one sObject and by clicking on get fields button ,it will display
field level and API name and the data type of it .

By clicking on the link you can export detail into an excel sheet .


public class FetchSelectedObjectFields {
    public String selectedObject {get; set;}
    public List <InrPair> InrField {get; set;}
    public List <SelectOption> objectNames {get; set;}
    public Boolean showTable {get; set;}
    public Boolean showButton {get; set;}
    public Boolean displayPB2 {get; set;}
    public Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public FetchSelectedObjectFields() {
        objectNames = initObjNames();
        InrField = new List<InrPair>();
        showTable = false;
        showButton = false;
        displayPB2 = false;
    }
    private List<SelectOption> initObjNames() {
        List<SelectOption> objNames = new List<SelectOption>();
        objNames.add(new SelectOption('blank', '--Select Object--'));
        List<Schema.SobjectType> obj = Schema.getGlobalDescribe().Values();
        for(Schema.SobjectType ss:obj) {
            objNames.add(new SelectOption(ss.getDescribe().getName(), ss.getDescribe().getName()));
            objNames.sort();
        }
        return objNames;
    }
   // Find the InrField for the selected object
    public void showFields() {
       InrField.clear();
       if(selectedObject != 'blank') {
            Map <String, Schema.SObjectField> fieldMap = schemaMap.get(selectedObject).getDescribe().fields.getMap();
           
            for(Schema.SObjectField sfield : fieldMap.Values()) {
                schema.DescribeFieldResult dfield = sfield.getDescribe();
                    InrPair fld = new InrPair();
                    fld.key = dfield.getName();
                    fld.val = dfield.getLabel();
                    fld.type = string.valueof(dfield.getType());
                    InrField.add(fld);
            }
            showTable = true;
            showButton = true;
            displayPB2 = true;
         }
         else {
            showTable = false;
            showButton = false;
            displayPB2 = false;
         }
    }
    public PageReference exportData() {
        PageReference pf = new PageReference('/apex/fetchObjData');
        pf.getParameters().put('objVal', selectedObject);
        pf.setRedirect(true);
        return pf;
    }   
    public class InrPair {
        public String key {get; set;}
        public String val {get; set;}
        public string type {get; set;}
    }
}
///////////////////////////////////////
<apex:page controller="FetchSelectedObjectFields" sidebar="false" >
 <apex:form >
  <apex:pageBlock id="pb1" >
   <apex:outputLabel ><b>Objects :</b></apex:outputLabel>&nbsp;
   <apex:selectList value="{!selectedObject}" size="1">
    <apex:actionSupport event="onchange"  reRender="detail"/>
    <apex:selectOption itemLabel="--Select Object--" itemValue="blank" />
    <apex:selectOptions value="{!objectNames}"/>
   </apex:selectList>&nbsp;&nbsp;&nbsp;
    <apex:commandButton value="Get Fields" action="{!showFields}" reRender="pb2"  status="fetchStatus" />&nbsp;  
     <apex:actionStatus id="fetchStatus" >
    <apex:facet name="start">
     <img src="/img/loading.gif" class="waitingImage" title="Please Wait..."/>
    </apex:facet>
   </apex:actionStatus>
  </apex:pageBlock>
  
  <apex:pageBlock id="pb2" > 
  <apex:outputPanel rendered="{!displayPB2}" >
   <apex:commandLink value="Export To Excel" action="{!exportData}" rendered="{!showButton}" target="_blank" style="font-weight:bold; font-size:15px; color:red" /> <br/><br/>
   <apex:pageBlockTable value="{!InrField}" var="fls" rendered="{!showTable}" >
    <apex:column headerValue="Field Value" value="{!fls.val}" />
    <apex:column headerValue="Field Name" value="{!fls.key}" />
    <apex:column headerValue="Field Type" value="{!fls.type}" />               
   </apex:pageBlockTable>    <br/><br/>
   </apex:outputPanel>
  </apex:pageBlock> 
 </apex:form>
</apex:page>
/////////////////////////////////////////////////
public class ExportFieldDetailInExcel {
    public List<InrPair> InrField {get; set;}
    public string str;
    public Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
   
    public ExportFieldDetailInExcel() {
        str = ApexPages.CurrentPage().getParameters().get('objVal');
        try{
            InrField = new List<InrPair>();
            if(str != 'blank') {
                Map <String, Schema.SObjectField> fieldMap = schemaMap.get(str).getDescribe().fields.getMap();
                for(Schema.SObjectField sfield : fieldMap.Values()) {
                    schema.DescribeFieldResult dfield = sfield.getDescribe();
                    InrPair fld = new InrPair();
                    fld.key = dfield.getName();
                    fld.val = dfield.getLabel();
                    fld.type = string.valueof(dfield.getType());
                    InrField.add(fld);
                }       
            }
         }catch(Exception e) {}  
    }
    public class InrPair {
        public String key {get; set;}
        public String val {get; set;}
        public string type {get; set;}
    }
}
/////////////////////////////////////////////////////
<apex:page controller="ExportFieldDetailInExcel" contentType="application/vnd.ms-excel#{!$CurrentPage.Parameters.objVal}.xls" cache="true" standardStylesheets="false"  sidebar="false" showHeader="false" >
    <apex:pageBlock >
        <apex:dataTable value="{!InrField}" var="fls"  >
            <apex:column headerValue="Field Value" value="{!fls.val}" />
            <apex:column headerValue="Field Name" value="{!fls.key}" />
            <apex:column headerValue="Field Type" value="{!fls.type}" />               
        </apex:dataTable>    
    </apex:pageBlock>
</apex:page>



Monday, 21 September 2015

Roll up Summery Trigger

Sales force provided standard roll up field facility in case of master detail relationship.However if you have lookup relationship and you want to built that functionality you need to built through trigger .
Below one example which has some  generic API names needs to  replace with specific .



1.Child_Object__c  needs to replace with child object API .
2.Parent_Object__c needs to replace with parent  object API
3.LookUpFld__c needs to replace with the lookup field API .
4.Parent_Fld_To__c  needs to replace with the parent filed to which roll up amount will update .
5.Child_Fld_From__c  Needs to replace with child field from the value will roll up .

trigger RollUpFromChildToParent on Child_Object__c ( after insert, after update,after delete,after undelete) {
Set<Id> prIdSet=new Set<Id>();
List<Parent_Object__c> pListToUpdate=new List<Parent_Object__c>();
if(Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete){
for(Child_Object__c cobj : Trigger.new){
   if(cobj.LookUpFld__c != null)
prIdSet.add(cobj.LookUpFld__c);     
        }
}If(Trigger.isDelete){
  for(Child_Object__c cobj : Trigger.old){
if(cobj.LookUpFld__c != null)
prIdSet.add(cobj.LookUpFld__c);     
        }
}
   for(AggregateResult res : [SELECT LookUpFld__c,sum(Child_Fld_From__c)can FROM Child_Object__c WHERE LookUpFld__c IN :prIdSet GROUP BY LookUpFld__c]) {
     pListToUpdate.add(new Parent_Object__c(Id=(Id)res.get('LookUpFld__c'),Parent_Fld_To__c=(Double)res.get('can')));
}
try{
 update pListToUpdate;
}catch(DmlException de){
 System.debug(de);
}
}


Tuesday, 15 September 2015

Schedule Apex in Depth

In general English Schedule means  a ​list of the ​times when ​events are ​planned to ​happen . 
What I believe that all naming convention are always with justification .So according to that in simple way if you want to planned any thing in future know as schedule .
Sales force has given that facility in apex ,report,data loader etc .

The class which implements the Schedulable interface is know as Schedule class in apex.
 We can execute that class in future automatically as per our need ,still have some limitations will discuss later .

We can schedule a class with help of standard sales force UI or by executing schedule method in system class .

Lets discuss in detail :

Basically Schedulable  Interface has only one method execute .

Below is the signature of the method which is in  System Names Space.

public void execute(SchedulableContext context) 

To know more detail about this method and class you can click  link  Interface Detail.


Once you will implement this interface then you need to implement execute method .

In execute method signature we need to pass instance of SchedulableContext what exactly it is and
why we have to pass this in method .
Again it is one more interface in Apex which has one method which will return the Id of corn trigger Object which stores the detail about the schedule Job.
You can look into the signature of the method which returns an id which is the CornTrigger record related to Schedule Job.

There are two objects related to Schedule apex .
1,Corn Detail

  •    Contains details about the associated scheduled job, such as the job’s name and type. 
  •    This object is available in API version 29.0 and later.
  •    Name contains the name of the job we are giving while executing the schedule class .
  •    Type is picklist which contains "7" for schedule apex ,As same object create record when we         are scheduling from any source i,e apex,report,data export .

2.Corn Trigger

  •      Contains schedule information for a scheduled job.
  •      Object is available in API version 17.0 and later.
  •       Major fields in this object are    below 


      1. CronExpression (while executing the class we are passing 3 parameter this is one )
      2. CronJobDetailId(Id od the corn detail)
      3.  StartTime(when the job started )
      4. EndTime(Till what time this job is schedule)
      5. PreviousFireTime(recently when the job fired)
      6. NextFireTime(Next when it will fire )
      7. TimesTriggered(How many times the job fired)
      8. State(Current job in which state),below are the picklist values

                                     WAITING—Job is waiting for execution.
                                    ACQUIRED—Job has been picked up by the system and is about
                                                             to execute.
                                    EXECUTING—The job is executing.
                                    COMPLETE—Trigger has fired and is not scheduled to fire again.
                                    ERROR—The trigger definition has an error.
                                    DELETED—The job has been deleted.
                                   PAUSED—This state during patch and major releases.After the  release, the                                                              job state is automatically set to WAITING or another state.


public Id getTriggerId()

To know more detail about this method and class you can click  link 

How to write Schedule class .

global class scheduledDemo implements Schedulable {
   global void execute(SchedulableContext scon) {
      //Here we need to write Business logic or we can call other class .
   }
}

Now this class you can either schedule with standard UI as discussed or you can schedule  by executing some code .

How to Schedule using standard UI .

To Schedule any class we need to follow below steps
Setup >> ApexClasses >> Click on Button (Schedule Apex)

Below image we need to give one name and the class which we need to schedule .Below image is for weekly view ,we can also select monthly view .






In case our requirement will not fulfill in standard UI ,we should build our own expression to achieve.

Lets discuss :












Friday, 28 August 2015

How to get RecordType Id in apex without SOQL

Basically to avoid SOQL Limit we can use dynamic apex to get RecordTypeId . So we can get a particular record type Id of a particulat Sobject or we can get all recordType id of one sobejct in map .
Here I have created one util class which has two methods .One will give you Id of particular recordType , however we need to pass the Sobejct Name and recordType Name as parameter .

Second method will return you a map of all recordType name and related Id ,where we need to pass only sobject name .

public class RecordTypeUtil {
     //Method to get the  recordTypeId 
     Public static Id recordTypeId(string obj,string recName){
        Id recTypeId;
        if(obj!= null && recName != null){
            recTypeId= Schema.getGlobalDescribe().get(obj).getDescribe().getRecordTypeInfosByName().get(recName).getRecordTypeId();
        }  
        return recTypeId;  
     }
    //Method to get the map of recordType Name as key and recordTypeId as value 
     Public static Map<String,Id> recordTypeMap(string obj){
        Map<String,Id> recTypeNameWithIdMap=new Map<String,Id>();
        if(obj!= null){
            for(Schema.RecordTypeInfo recInfo : Schema.getGlobalDescribe().get(obj).getDescribe().getRecordTypeInfosByName().values()){
                recTypeNameWithIdMap.put(recInfo.getName(),recInfo.getRecordTypeId());
            }
        }
        return recTypeNameWithIdMap;
    } 
}


Both are static methods you can call with class name like below .
Example 1.


Id recId=RecordTypeUtil.recordTypeId('Account','Draft');

Example 2.

Map<String,Id> recTypeIdMap=RecordTypeUtil.recordTypeMap('Account');
 
If you want only single record type Id then you can also use below code which 
 will give you particular record type id of a object . Just replace object name/record type 
Name of your desired .
 
Id recordTypeId = Schema.SObjectType.OBJECT NAME.getRecordTypeInfosByName().get('RecordType Name').getRecordTypeId(); 

I think this will help please suggest to improve .


Wednesday, 1 July 2015

ApexPages.currentPage().getParameters().get('id')

Basically all developer using  the above code , I had a confusion when I have used this first time . At that time apex pdf does not have clear definition of methods and classes .
This is the concept of method chaining .

I have divided into 3 steps to know detail concept behind it .

Step1:-
ApexPages is a class in which CurrentPage is a method which returns a PageReference .

Click on the link ApexPages_methods to know about the method and other methods as well .

Step2:-
As step one returns a PageReference  now we can use PageReference method in step2
ApexPages.currentPage().getParemeters()
getParemeters() is a method in PageReference class which retuns a Map .

Click on the link PageReference_methods to know about the method and other methods as well .

Step 3 :-
ApexPages.currentPage().getParemeters().get()/put()

As step2 returns Map so we can use map methods in step3 .
Click on the link Map_methods to know about the method and other methods as well .

What else we can do with it : -

1.You can get the full url by using belwo code :

ApexPages.currentPage().getUrl();

2.You can get the IP address from belwo code .

ApexPages.currentPage().getHeaders().get('X-Salesforce-SIP');







Wednesday, 3 June 2015

Tips and Tricks For Test Class

Why we  need to write test class ? Some people will answer like we need code coverage to deploy code to production, as we don't have right to write code in production directly  . Yes it is correct but not 100 percent  .Test class  basically helps us to test our functionality of code which is important to develop  a better application . So we should not concentrate only code coverage though it is required  .
We should write proper test case to test all types of scenario . We should not happy with 75 % code coverage ,we should try to achieve 100 % coverage with all test scenario like  positive ,negative and bulk unit test .


Below points we should know as a developer :-

  • Test class must start with @isTest annotation if class class version is more than 25
  • Test environment support @testVisible, @testSetUp as well
  • Unit test is to test particular piece of code working properly or not .
  • Unit test method takes no argument ,commit no data to database ,send no email ,flagged with testMethod keyword .
  • To deploy to production at least 75% code coverage is required and al test case should pass .
  • System.debug statement are not counted as a part of apex code coverage .
  • Test method and test classes are not counted as a part of code coverage .
  • We should not focus on the  percentage of code coverage ,we should make sure that every use case should covered including positive, negative, bulk and single record .
  • Single Action -To verify that the the single record produces the correct and expected result .
  • Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200 records .
  • Positive behavior : Test every expected behavior occurs through every expected permutation , i,e user filled out every correctly data and not go past the limit .
  • Negetive Testcase :-Not to add future date ,Not to specify negative amount.
  • .Restricted User :-Test whether a user with restricted access used in your code .
  • .Conditional and ternary operator are not considered executed unless both positive and negative branches are executed .
  • Unit test are class methods that verify whether a particular piece of code is error free or not .
  • Test class should be annoted with isTest .
  • isTest annotation with test method  is equivalent to  testMethod keyword .
  • Test method should static and no void return type .
  • Test class and method default access is private ,no matter to add access specifier .
  • Classes with isTest annotation can't be a interface or enum .
  • Test method code can't be invoked by non test request .
  • Stating with salesforce API 28.0 test method can not reside inside non test classes .
  • @Testvisible annotaion to make visible private methods inside test classes.
  • Test method can not be used to test webservice call out .Instaed use call out mock .
  • You cann't  send email fron test method.
  • User,profile,organisation,AsyncApexjob,Corntrigger,RecordType,ApexClass,ApexComponent,ApexPage we can access without (seeAllData=true) .
  • SeeAllData=true will not work for API 23 version eailer .
  • Acessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,'ResourceName').
  • Create Test Factory class with isTest annotation to exclude from organization code size limit .
  • @testSetup to create test records once in a method  and use in every test method in the test class .
  • We can run unit test for a specific class, set of classes and all classes .
  • We can run unit test by using Salesforce Standard UI,Force.com IDE ,Console ,API.
  • Maximum number of test classes run per 24 hour of period is  not grater of 500 or 10 multiplication of test classes of your organization.
  • As apex runs in system mode so the permission and record sharing are not taken into account . So we need to use system.runAs to enforce record sharing .
  • System.runAs will not enforce user permission or field level permission .
  • Every test to runAs count against the total number of DML issued in the process . 

Below code snippet help you to start writing test class :-

Test class definition :-
Sample 1-
@isTest
private class MyTestClass {}
Sample 2-Grant test classes to  access  all data in the organization.
@isTest(SeeAllData=true)
private class MyTestClass {}
Sample 3: Specify whether test class execute during package installation or not 
@isTest(OnInstall=true/flase)
private class MyTestClass {}
Test method definition :- Sample 1-with testmethod keyword . static testMethod void testName() { // code_block } Sample 2:-Here we can avoid testMethod with @isTest annotation which will help us to get benifit of parameters indivisually incase not there in class level . @isTest static void testName() { // code_block }

Below tips  helps us to move towards 100 % code coverage :-

1.Tips for standardcontroller

ApexPages.standradController con=ApexPages.StandradController(Needs to pass the instance of the standard/Custom Object);

2.StandardSetcontroller

ApexPages.standradSetController con=ApexPages.StandradSetController(Needs to pass the list of the standard/Custom Object);

3.For wrapper class

ClassName.WrapperclassName wrp=new ClassName.WrapperclassName();

4.Test code catch block .

We need to create a excption in test method to cover .We can do in two different ways one suppose we want an excption on update .we can do like below .

 Trick 1-

Account acc =new Account();
try{
  insert/update acc;
}catch(Exception ex){}
As mandatory fields are missing it will throw exception and it will cover the catch block .
Trick 2-We need to add two line  of code in class like below .
try{
   DML statement;
if(Test.isRunningTest())
Integer intTest =20/0;
} catch(Exception ex){
ApexPages.Message msg = new              ApexPages.Message(ApexPages.Severity.error,qe.getMessage());
ApexPages.addMessage(msg);
}
     
There is a class named Test in apex which has some method which help us to write some useful test case   Test class method




Batch Apex in Depth

Basics of batch apex :-

Apex class that implements the Database.Batchable Interface is known as batch class .
We are basically using batch apex to avoid some governor limits .
There are two interface in  Database Namespace .
1.Batchable
Below are methods in Batchable interface
Public System.Iterable start(Database.BatchabelContext bcon)
Public Database.QueryLocator start(Database.BatchabelContext bcon)
Public void execute(Database.BatchableContext bc,List<Sobject> scope)
Public void finish(Database.BatchableContext bc)
2.BatchableContext
Below are the methods in the interface
 Public Id getJobId()
 public Id getChildJobId()
Basic thing is that once you will implement Batchable interface in your class you have to implement three methods in that interface .

Flow is that when you execute your class start method will execute once and return a list in two different form as we have two types of return type in start method .
The list which will return from the start method will available in execute methods scope execute method will execute according to your batch size .
Assume that you have 1000 record ,if you set your batch size as 100 then your execute method will execute 10 times .
Finally the finish method will execute once the execute method will complete the execution .
Basically in the signature of all method one common parameter we are passing named BatchabelContext, this is to get the batch  JobId and childJobId .
Both method returns the id of  "AsyncApexJob" object record , where  both have self relationship and child record will have different type and contain the last executed record id .

How to write simple  batch class :-

Below example will help you to update all account name with post fix as UpdatedbatchApex .
Here start method will return a list of account which will pass to the scope of execute method ,scope size will depends on your batch size which you will defined while executing the batch class . 

  global class AccountUpdateBatch implements Database.Batchable<sObject>{
    global Database.QueryLocator start(Database.BatchableContext BC){
        String query = 'SELECT Id,Name FROM Account';
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, List<Account> scope){
         for(Account acc : scope){
             acc.Name = acc.Name +'UpdatedByBatch';            
         }
         update scope;
    }   
    global void finish(Database.BatchableContext BC){ }
}

How to execute the batch apex :-
In Database class there are two static method
executeBatch(Instance Of class )
excecuteBatch(InstanceOf batch class ,batchsize )

If you want to defined any limit of record to pass into execute method per execution then you need to use second method .Batch size can very from 1-2000.
If you will call first method then it will take the default batch size as 200.

Batch Apex Governor Limits:-
  • All methods in the class must be defined as global or public.
  • Up to 5 batch jobs can be queued or active concurrently.
  • In a running test, you can submit a maximum of 5 batch jobs.
  • The maximum number of batch Apex method executions per a 24-hour period is 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater.
  • You cannot use the getContent and getContentAsPDF PageReference methods in a batch job.
  • The start, execute, and finish methods can implement up to 10 callouts each.
  • In a running test, you can submit a maximum of 5 batch jobs.
  • A maximum of 50 million records can be returned in the Database.QueryLocator object. If more than 50 million records are returned, the batch job is immediately terminated and marked as Failed.
  • Start method can have up to 15 query cursors open at a time per user.
  • Execute and finish methods each have a limit of five open query cursors per user.




Tuesday, 5 May 2015

Restrict User To Select Past Date Using Custom Date Picker

In salesforce standard date picker we can not restrict user to select past date so we need to write validation .
Below code will help to restrict user to select past dates without validation .

//VF pages
<apex:page id="pg" controller="CustomDatePicker">
<head>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    <link rel="stylesheet" href="/resources/demos/style.css" />
    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />
 </head>  
    <script>
       $(function(){
        $('.datepicker').datepicker({ minDate: 0 }).on('changeDate', function(ev){
            $('#sDate1').text($('#datepicker').data('date'));
            $('#datepicker').datepicker('hide');
        });
 
    })
    </script>
    <apex:form id="frm">
        <apex:inputText id="datepicker" styleClass="datepicker"  value="{!currentDateValue}"/>
        <apex:commandButton action="{!getValue}" value="getvalue"/>
    </apex:form>
 </apex:page>

 //Apex class
 public class CustomDatePicker {
    public String currentDateValue { get; set; }
    public void getValue(){
      System.debug('*************'+currentDateValue);
    }
}
//Below script will help you to get date in different format
<script>
       $(function(){
        $('.datepicker').datepicker({minDate: 0 ,dateFormat: 'dd/mm/yy' }).on('changeDate', function(ev){
            $('#sDate1').text($('#datepicker').data('date'));
            $('#datepicker').datepicker('hide');
        });
 
    })
</script>

I will suggest to down load the JQuery Librery from below link and add in static resource and use in page .

http://jquery.com/download/



Saturday, 18 May 2013

Master in Salesforce Apex collection

Before starting collection ,My first question is what is the meaning of collection? Why collection came to picture ?
Collection is nothing but a group of elements.So Now my question  is,  how can we handle a group of elements?  Ok we can handle a group of elements with help of array.My next question is Can we handle a group of objects with the help of array ? yes we can ,but still why we need collection ? What are the inconveniences  for which we need collection?
Below are the drawback with array for which we need collections.
1.We can not store different class objects into the same array, reason is that array can store a single data type.
2.We can add an element to the end of the array.But inserting and deleting  an element to the middle of the array is difficult.
3.We can retrieve the elements from the array but there is no such methods to process the elements.

Due to such problems  developers wants an object to store a group of  objects .Such an object is nothing but collection.

For a java developer apex collection is very simple, because java collection frame work  has a lot of classes,abstract classes and also interfaces.

Sales force Apex  has  only three types of  collections.
1.List :-
    List is an ordered collection of primitive,sObjects,userdefind objects,apex objects or collection that are distinguished by indexes.We can add duplicate element in the list.
List are index-based so the index position of first element in a list is always zero(0).
List can have upto five level of nested collection inside it.
2 . Set :-
      A set represents a group of  elements arranged just like an array. Set will grow dynamically    when the elements are stored into it .  Set elements can be of any data type—primitive , collections, sObjects, user-defined types, and built-in Apex types.Set will not allow duplicate elements.

3.Map:-
       A map is a collection of key-value pairs ,where key should be  unique and value can be duplicate . Each unique key maps to a single value.Through the key we can retrieve values.  
Keys and values can be any data type—primitive types, collections, sObjects, user-defined types, and built-in Apex types. 

Note : There is no such  limit on the number of items a collection can hold. How ever there is a general limit on  heap size.

All collection in apex are ordered from 34 version on wards .

Lets play with the methods of different collection.

List class have some methods ,just click on the link   list methods    to  refer  all list methods .

Set class have some methods ,just click on the link   set methods    to  refer  all Set methods .

Map class have some methods ,just click on the link   Map methods    to  refer  all map methods .


I think now we are familiar with all methods in above three classes .
Lets discuss one real time scenario where we can implement collection to over come the limits .

Here is one scenario like when you will update any  account owner then related contact owner should update with same value

Below is the trigger code which can write in Account and test it will work ,however in case of mass update it will give you error .

1.101 SOQL error because contact query is inside the for loop .
2.Too many  DML rows: 10001 .

Trigger updateownerofcontact on Account(before update) {
 for(Account currentAccount : trigger.new) {
  if(currentAccount.OwnerId != Trigger.oldMap.get(currentAccount.Id).OwnerId){
   for(Contact con: [SELECT Id, OwnerId, AccountId FROM Contact
                     WHERE  AccountId = :currentAccount ]) {
    con.OwnerId=currentAccount.OwnerId;
    update con;
   }
  }
 }
}
 
To avoid this we need to use collection ,check below code where collection
used to avoid all above error .
Here we need to remove contact query and update statement to out of for  loop 
  
Trigger UpdateOwnerOfContact on Account(before update) {
 //Map to collect account id with changed owner id(user id ) .
 Map<Id,Id> accIdWithOwnerIdMap = new Map<Id,Id>();
 List<Contact> listOfContactsToUpdate = new List<Contact>();
 for(Account currentAccount : trigger.new) {
     if(currentAccount.OwnerId != Trigger.oldMap.get(currentAccount.Id).OwnerId){
        accIdWithOwnerIdMap.put(currentAccount.Id,currentAccount.OwnerId);
     }         
 }
 if(!accIdWithOwnerIdMap.isEmpty()){
  for(Contact con: [SELECT Id, OwnerId, AccountId FROM Contact 
                    WHERE AccountId IN :accIdWithOwnerIdMap.keySet() ]) {
   con.OwnerId = accIdWithOwnerIdMap.get(con.AccountId);
   listOfContactsToUpdate.add(con);
  }
 }
 if(!listOfContactsToUpdate.isEmpty()) {
  try{
   update listOfContactsToUpdate;
  }catch(DmlException de){
   System.debug(de);
  }
  
 }




Saturday, 9 March 2013

Concept of Salesforce Trigger

If I will ask question ,what is a  trigger in salesfore ? Is it a class,an Object or apex code ? Most of the people will answer Trigger is an apex code ,yes it is correct ,However rest two are also correct .
Trigger is an object where for each trigger we have written , Sales force will create a record in ApexTrigger object .To know more detail click on the link Trigger object details or login to workbench and select the object .
Trigger is also a class which contains twelve static context variable we will discuss in detail .

Salesforce  trigger executes when we do some DML operation in salesforce object.
In order to execution of trigger it is broadly  of two types ,After Trigger and Before Trigger.
Basic syntax of trigger:-
trigger triggerName on ObjectName (trigger_events) {
    //code_block
}
trigger TestTrigger on Case (Before Insert,After Insert,Before Update ,After Update ,Before Delete ,After Delete,After Undelete) {
 //Code Block
}

[Note:-Keep in mind that only the trigger of that particular object will invoke in which object we will do DML operation, not like  you will insert a record in child object and the trigger in parent object will invoke . It is possible to do  some data manipulation in different object but any way the trigger invoke only the object in which we will do Dml operation].

We can declare more than one trigger event in one trigger ,but each should be separated by comma.
Below are the possible event for trigger.

 >>Before Insert
>>Before Update
>> Before Delete
 >>After Insert
 >>After Update
 >>After Delete
>> After Undelete

There is a System defind class called Trigger which contains 12(twelve) implicit variable,which we can access at run time.
Below are the varibales with description.

1.isExecuting-It rutuns ture if the any code inside trigger context is executing.That means you can test whether your trigger is excuting or not by the help of this variable.It may be from salesforce user interface .apex or  any API


2.isBefore-It rutuns ture if the any code inside trigger context is executing before record is saved to the database.It may be from salesforce user interface .apex or  any API


3.isAfter-It rutuns ture if the any code inside trigger context is executing after record is saved to the database.It may be from salesforce user interface .apex or  any API


4.isInsert-It rutuns ture if the any code inside trigger context is executing due to an insert operation.It may be from salesforce user interface .apex or  any API

5.isUpdate-It rutuns ture if the any code inside trigger context is executing due to an update operation.It may be from salesforce user interface .apex or  any API


6.isDelete-It rutuns ture if the any code inside trigger context is executing due to a delete operation.It may be from salesforce user interface .apex or  any API


7.isUnDelete-It rutuns ture if the any code inside trigger context is executing due to undelete operation  i,e when we recovered data from recycle bin .It may be from salesforce user interface .apex or  any API .


8.new-It returns the new version of the object records.Suppose you have inserted/updated 10 records trigger.new will contain that 1o records .

9.newMap-It returns a map  which contains an IDs  as a key and  the old versions of the sObject records as value.This map is only available in before update, after insert, and after
update triggers.

10.old-It returns the old version of the object records

11.oldMap-It returns a map  which contains an IDs  as a key and  the new versions of the sObject records as value.This map is available for only update and delete trigger.

12.size- It return the size of the manipulated record .It will return one if you will insert one record, It will return the size of the record you are inserting ,updating or deleting or undeleting.

13.Operation Type- This will return an Enum(TriggerOperation) .  Below are the values in enum .
   
  • AFTER_DELETE
  • AFTER_INSERT
  • AFTER_UNDELETE
  • AFTER_UPDATE
  • BEFORE_DELETE
  • BEFORE_INSERT
  • BEFORE_UPDATE


Examples to test the implicit variable:
trigger  TestTrigger on Case (Before Insert,After Insert,Before Update ,After Update ,Before Delete ,After Delete,After Undelete) {
    System.debug('*********testExecution*************'+Trigger.isExecuting);
    System.debug('****************size of trigger***************'+Trigger.size);
    if(Trigger.isBefore){
        if(Trigger.isInsert){
            for(Case cs:Trigger.new){
                System.debug('********beforeInsertNew************'+Trigger.new);
            }
        }
        if(Trigger.isUpdate){
            for(Case cs:Trigger.new){
                System.debug('********beforeUpdateNew************'+Trigger.new);
                System.debug('**********beforeUpdateOld**********'+Trigger.old);
                System.debug('********beforeMapUpdateNewMap************'+Trigger.newMap);
                System.debug('**********beforeMapUpdateOldMap**********'+Trigger.oldMap);
            }
       }
        if(Trigger.isDelete){
            for(Case cs:Trigger.old){
             
                System.debug('**********beforeDeleteOld**********'+Trigger.old);
                System.debug('**********beforeMapDeleteOldMap**********'+Trigger.oldMap);
            }
      }
  }
    if(Trigger.isAfter){
        if(Trigger.isInsert){
             for(Case cs:Trigger.new){
                System.debug('**********afterInsertNew**********'+Trigger.new);
                System.debug('**********afterInsertNewMap**********'+Trigger.newMap);
             }
         }
        if(Trigger.isUpdate){
             for(Case cs:Trigger.new){
                System.debug('**********afterUpdateNew**********'+Trigger.new);
                System.debug('*************afterUpdateOld*******'+Trigger.Old);
                System.debug('**********afterUpdateNewMap**********'+Trigger.newMap);
                System.debug('*************afterUpdateOldMap*******'+Trigger.oldMap);
            }
        }
       if(Trigger.isDelete){
            for(Case cs:Trigger.old){
                System.debug('*************afterDeleteold*******'+Trigger.Old);
                System.debug('*************afterDeleteoldMap*******'+Trigger.oldMap);
            }
       }
       if(Trigger.isUnDelete){
            for(Case cs:Trigger.new){
                System.debug('**********afterunUndeleteNew**********'+Trigger.new);
                System.debug('**********afterunUndeleteNewMap**********'+Trigger.newMap);
             
           }
       }
    }
}
[Note: Just copy this code and paste in case object or else in which object you want to test just the object name you need to change in the above example.After saving the trigger you can insert ,update ,delete and undelete records and just create debug log for different situation and observe.]

Below is the steps how to add this trigger in sales force in case object.
click Your Name ➤ Setup ➤ Cases ➤ Case  ➤ Triggers ➤ New
Just remove the existing code and paste the above code ans save the code .
After that follow the below steps to create the debug log.
click Your Name ➤ Setup ➤ Monitoring➤ Debug logs  
Click on New button to set the debug log in your name .
Now you can create record for case object and try to observe the debug log and just realize all context variable.
Just Insert ,update delete and undelete one record from recycle bin.

Also you can write trigger from developer console 

In the Developer Console, click File | New | Apex Trigger. 

 Click the below link for some more concepts on before insert trigger .

Before insert conecpt