Sunday, 30 December 2018

what is Force.com ?


Basically there are three models of cloud service.

1. Infrastructure as a service
ex : Amazon AWS
     Rackspace
     Heroku

2.Software as a Service

ex : Google Apps
     Zoho
     Quickbooks or Quicken Online
     Salesforce.com CRM offerings(includes Force.com)

3.Platform as a service
  ex : Google App Engine
       Microsoft Azure
       Heroku
       Force.com

Note :

1.Salesforce.com CRM cloud offerings better fit under software as a service.

saas is sotfware and all it's various features,paid for in an on-demand model,accessed over the internet,typically run in a browser;which means there's nothing to install on your computer,
nothing to upgrade or backup or patch.

-> Software features available on-demand
-> Accessed over the internet
-> No programs to install
-> Upgrades in the background
-> No infrastructure to support.

2. Force.com fits under Platform as a service.

PaaS is platform features supporting application development,paid for in an on-demand model.

-> Platform features and services available on-demand
-> Supports building applications
-> A subset of SaaS

Force.com is an on-demand application development platform.And it provides infrastructure and support,security services, database services,Web services APIs, Application logic,User Interface,etc.

-> Force.com is PaaS.

Services Across the Stack:
====================
1.Metadata driven functionality
2.Declarative Customization (Clicks and code)
3.Programmatic Customization (APEX and Visualforce)
4.User Authentication and Authorization
5.Multi-Featured (Sales and Service Cloud CRM)
6.Social Networking (Chatter)
7.Declarative Data Modeling (Objects,Fields,Relationships)
8.Programmatic Record Level Data Security (APEX Sharing)
9.Declarative Business Logic (Validations,Workflow,Approvals)
10.Infrastructure Security (IP Login Range,Login Hours)
11.International Localization (Translation Workbench)
12.Messaging and Notifications (Email Services,Outbound Messages)
13.Monitoring and Logging
14.Polymorphic Behavior
15.Memory Management
16.Metadata Synchronization
17.Transactional Data Persistence

APIs :
======
Apex web services :
-> SOAp
-> Rest

Data APIs
-> SOAP
-> REST
-> BULK
Streaming API
Chatter API
Metadata API

what makes Force.com SOA(service-oriented architecture)?

A service-oriented architecture is essentially a collection of services that communicate with each other, typically over the internet.

They can be simple or complex in nature. This can involve multiple services, coordinating some kind of process or activity,or simply be passing around a collection of data,potentially across disparate systems.

Force.com Service Layers :
====================
In force.com,Multiple native SOAP and REST APIs exist,allowing access to virtually all data and processing capability of any Salesforce or Force.com applications.


Note :
1.Native SOAP and REST APIs already exist.
2.Expose built-in and custom data and capabilities.
3.Allows tight integration with external systems.
4.Apex custom logic can callout(SOAP or REST).
5.Apex custom logic can be called-build your own API(SOAP or REST)
6.Apex can send and receive email.
7.Leverage UI mash-ups in Visualforce,Force.com sites and Portals.

Force.com Security :
====================
1.The Force.com security layer is multidimensional,highly configurable and very robust.

2.it has a sophisticated authentication mechanism that also supports multiple flavors of single sign-on and identity management,including many different OAUTH security flows. And,you're Salesforce instance can be either an identity provider or just a service provider or both.And you can leverage third-party identity providers,such as Facebook or Google.

3.User Profile Based Authorization

-> System Access(Protected IP Ranges and Login Hours)
-> System Features,Capabilities,UI,Navigation.
-> Object,Field and Record Level security
-> Reporting,Analytics and Document Security
-> APEX Classes and Visualforce

4.Remote/Mobile Application

Features As Services :
======================
1.Notifications
-> Highly customizable and data centric
-> Apex Email Services- Outbound/Inbound
-> Outlook and Gmail Integration
2.Workflow
-> Send Email
-> Assign Tasks
-> Updates Fields
-> Send SOAP outbound Messages
3.Multi-Step Approval Process
4.Social Collaboration - CHATTER

SOAP API :
=============
1.mature and robust
2.Manages standard and custom objects
3.Query,Search,Retrieve,Create,Update, Upsert,Delete,Undelete
4.Limited administrative capabilities.

 it allows some minimal utility and admin capabilities,such as resetting a user's password information,sending e-mails,and launching approval processes.

5.Obtain metadata information
6.Enterprise and partner WSDLs

The enterprise WSDL,for a hard-type representation of all standard and custom data objects and fields. The partner WSDL,that allows more generic access to any salesforce.com instance.

7.Include authentication service calls
8.It is designed to process data in batches of up to 200 records at a time.

9.Supports complex relational data synchronization.

it support for complex,relational data integration and synchronization, leveraging the Force.com external ID mechanism.

10.Not efficient for high volume processing > 1m rows

REST API :
=============
1.Similar functionality to the SOAP API.
2.Light weight
3.No WSDL required
4.Light data volume
5.Designed for mobile and web
6.Supports JSON and XML
7.Utilize hypermedia design
8.Discoverable and explorable.

it's discoverable and explorable capability allows developers to essentially surf the API,using tools
like the Developer's Workbench.

BULK(REST) API :
================
1.RESTful API processes large data sets(<50m rows)
2.Query,insert,update,upsert,delete or hardDelete.
3.Optimized for high volume jobs with
10K record batches.
4.Data is streamed to the Force.com servers.
5.Asynchronous background processing.
6.Batch and Job results can be queried.
7.Relies heavily on XML and CSV(not JSON).

Metadata(SOAP) API :
=====================
1.Developer Centric API
2.For CRUD operations on meta data
3.Includes object and field schema, page layouts,profiles etc.
4.used to migrate meta data - Not business data.
5.Used in developer tools.

ex : The Force.com IDE Eclipse add-in and the Force.com migration toolkit that works with ANT are both built on top of the API,to allow developers to manage customizations.

Streaming(REST) API :
======================
1.Real Time push technology
2.Notifies of changes to standard or custom object data.
3.Publish and Subscribe model
4.use the openBayeux Protocol and Ajax CometD libraries.
5.Social networking applications.

it's commonly used with social networking applications that process and stream feeds.

6.Reduce network traffic
7.Replaces Ajax Polling patterns.

Apex SOAP and REST APIs :
===========================
The Force.com Apex SOAP and REST APIs allow developers to create custom web services in the form of Apex class methods,to perform complex operations and business processes.

For SOAP web services,developers can declare a class method as static web service.

For REST Resources,developers can declare a class with @RestResource.

Custom Apex class methods are mapped to the standard HTTP verbs by decorating them with a declaration indicating which HTTP verb they should correspond to.

DELETE,GET,PATCH,POST,PUT.

Both SOAP and Rest web methods can leverage Apex helper classes for JSON and XML serialization,encoding,and encryption support.

Chatter REST API :
===================
1.Optimized for social and processing
2.Users,groups,followers,feeds,files,pictures.
3.Localized to the user's locale
4.Chatter data is available through other APIs
5.Reduces development effort to manage:
-> Hierarchical data graphs,relationships and keys
-> Social network processes
6.Similar to Twitter and facebook.

AJAX Toolkit :
===============
The Ajax toolkit is not a web service, but rather a javascript API that acts as a wapper,allowing calls to the SOAP API from Ajax,embedded in webpages, including Visualforce.


Thursday, 27 December 2018

what is metadata ?

Metadata :
===========

what is it ?

Metadata is persisted information that describes your application's functionality and representation.And metadata is at the core of the force.com platform.

In a more traditional development environment,developers use code either interpreted or compiled.And when executed, it determines the behaviour of an application.

Force.com uses a dynamic engine -- we'll call it the Kernel-- that reads any org's metadata that identifies how the application behavior and appearance is configured.

1. metadata distinguishes any force.com application from any other.
2.Developer have control major portions of metadata and are,therefore, able to customize their applications.
3.A sales force instance,or org,is nothing more than a container for metadata,as well as business data.

what does it do ?

1.metadata describes your org and describes your applications.
2.metadata describes your data and logic.

Everything in your org is described in metadata,from objects in fields, to declared business rules,workflow, reports and security permissions, even your Apex code and Visual force
pages,pretty much everything.

3.metadata drives the engine and as the kernel generates application components from metadata at run time, it forms the foundation of any instance in the platform's multi-tenant
infrastructure.

so metadata controls all aspects of what the platform offers. without metadata,there could be no
multi-tenant paradigm.

4.Every tenant on the platform can maintain their own set of partition metadata,the multi-tenant Kernel can serve multiple applications of varying data structure,with varying look and feel,and varying business logic in a completely decoupled and scalable manner.

5.Only the generic database,resources,and core logic of the kernel are shared.Everything about tenant applications is dynamic,driven by the metadata.

what does it look like ?

we don't really know.Like most elements of the force.com, the abstraction layers hide and protect much of what's in the cloud.That's their job.

The physical database tables that store the actual metadata in rows and columns are not accessible to developers.

However,much of the metadata is visible through developer tools and via the APIs.

When you connect your force.com org to the force.com IDE,you can download metadata and store it in files on your hard disk.The IDE allows you to modify the files and push them back up to
your org.

Most metadata objects represent in  XML structures.Apex and Visualforce also appear as traditional programming language code.Although,you'll find they're also tied to XML content as well.

How do I manage it?

Most non-programmers depend on the setup menu to declaratively configure the metadata in point and click wizards. it the fastest and most efficient way to perform much of the configuration.

ways to get metadata :
======================
1.The metadata API,one of the many platform web services, allows developers to perform crud operations on metadata, effectively allowing you to program your applications by managing data
operations.

2.The force.com IDE and force.com migration kit, which are both built on top of the API,are just two tools that let developers manage metadata.

Note :
Now keep in mind,that while a lot of metadata is accessible to you,other metadata is not necessarily even visible.There also exists metadata that is managed behind the scenes that you can't change even though you might be able to see it.

Sunday, 4 November 2018

Force.com Integrations

Integrations :
==============
Force.com offers excellent support for integration with other platforms.

outbound :
==========
On the outbound side making callouts ,it supports both SOAP and REST ,or you can use direct web requests using Get or Post.

your ability to make callouts depends on the execution context.For example you cannot make callouts during a trigger.

Note : However,there is no limit to the number of callouts you can make over a 24-hour period.

Inbound :
==========

The salesforce Platform supports many different APIs that external applications and services can use to call into your organization.

1.Standard APIs

 Metadata ,Tooling and Apex APIs    :
===========================
The metadata API allows you to import, export and modify system metadata.

The Tooling API and Apex APIs also allows you to work with metadata but are particularly intended for use by external developer tools allowing you,for example,to run unit tests and review code coverage results.

 Analytics API  :
==============

The analytics API allows you to run reports and view the resulting data sets.

Streaming and Bulk APIs :
=====================

The streaming API allows you to subscribe to an org and watch for changes in org data.

The bulk API provides a mechanism for transferring large amounts of data to and from an org.

 Partner API,REST API and Enterprise APIs :
=================================

The partner API,REST API and Enterprise APIs allow external applications to perform direct operations on your organization data much as you would in Apex.

They can query for describe information to find out about the objects and fields defined in an org.

They can query and search for data.They can perform DML operations to retrieve,set and delete data.

The partner API is a SOAP API whose WSDL you can obtain using the API settings in your
salesforce org.

The REST API has comparable functionality for those who prefer to use REST instead
of SOAP.

Note : REST API is newer and may not support all of the features of the platform API,nor does anyone guarantee that every feature in the REST API is implemented in the partner API.


The Enterprise API is also SOAP based, but the WSDL it generates is specific to the organization from which it is downloaded.

it reflects the organization's metadata,and this provides data types that correspond to the specific objects,fields and metadata in an organization

This can simplify the external programming considerably as the generated proxy
object will contain elements that correspond exactly to the objects and fields in the specific org.

Note : we Typically prefer to use the Enterprise API when writing an external application that is specific to one org or customer.

The partner API when creating external applications designed to work with salesforce orgs in general.



Partner,Enterprise and REST API :
=========================
Partner API

soap
describe,query,DML on any org.

Rest API

HTTP/REST

Describe,query,DML on any org

Enterprise API

SOAP
Describe,query,DML on specific org.

Custom API :
=============
Define your own SOAP or REST
endpoints using Apex.

Thursday, 1 November 2018

Custom Settings vs Custom Metadata in Salesforce


Custom Settings :
===============

You can deploy the custom setting definition between orgs,but the data must be transferred separately.

Records can be created,modified and deleted using Apex DML.

Preferred for managed packages and scenarios with custom configuration UI in visualForce or Lightning.

Custom Metadata :
================

You can deploy the custom metadata types and the custom metadata records between orgs.

Records can be created,modified and deleted from the UI or metadata API-but not through Apex.

Preferred for development in specific organizations where custom configuration UI is not required.

Saturday, 6 October 2018

Lightning Component For Custom RecordType Selection

Apex Controller:

Here, we are getting List of RecordTpes from Account Object.

public class RecordTypeSelectorController {
 
    @AuraEnabled
    public static List<RecordType> getListOfRecordType(){
        String query = 'SELECT Id,Name FROM RecordType WHERE SobjectType =\''+'Account'+'\' ';
        List<RecordType> rtNames = new List<RecordType>();
        Schema.SObjectType  objType = Account.SObjectType;     
        for(RecordTypeInfo rt : objType.getDescribe().getRecordTypeInfos()){
            System.debug('rt.getName()'+rt.getName());
            rtNames.add(new RecordType(Id = rt.getRecordTypeId(),Name = rt.getName()));
            System.debug('rtNames'+rtNames);
        } 
        return rtNames; 
    }
}


Lightning Component:

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes" controller="RecordTypeSelectorController" access="global">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" access="public"/>
    <aura:attribute name="recordTypes" type="String[]" access="public"/>
    <div class="slds">
        <div class="demo-only" style="height: 640px;" id="newClientSectionId">
            <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
                <div class="slds-modal__container">
                    <header class="slds-modal__header">
                        <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close">
                            <lightning:icon iconName="utility:clear" size="small" alternativeText="Indicates approval"/> 
                            <span class="slds-assistive-text">Close</span>
                        </button>
                        <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">RecordType Selection</h2>
                    </header>
                    <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                        <aura:iteration items="{!v.recordTypes}" var="rt">
                            <ol class="slds-list--vertical slds-list--vertical-space">
                                <input type="radio" value="{!rt.Name}" name="recordTypeRadio" id="{!rt.Id}" style="margin-right: 5px;" />{!rt.Name}
                            </ol> 
                        </aura:iteration>
                    </div>
                    <footer class="slds-modal__footer">
                        <button class="slds-button slds-button_brand" onclick="{!c.createRecordFun}">Next</button>
                    </footer>
                </div>
            </section>
            <div class="slds-backdrop slds-backdrop_open"></div>
        </div>
    </div>

</aura:component>

JavaScript Controller:

Here, we are using force:createRecord event. This event tells app to use standared create record page.

({
    createRecordFun : function (component, event, helper) {
        var rtDet = document.querySelector('input[name="recordTypeRadio"]:checked');
        if(rtDet != null) {
            document.getElementById("newClientSectionId").style.display = "none" ;
            var createRecordEvent = $A.get("e.force:createRecord");
            createRecordEvent.setParams({
                "entityApiName": "Account",
                "recordTypeId":rtDet.id
            });
            createRecordEvent.fire();
        } 
    },
    doInit : function(component, event, helper) { 
        helper.RecordTypeSelectorController(component); 
    }

})

JavaScript Helper:

({
   RecordTypeSelectorController: function(component) {
    var action = component.get("c.getListOfRecordType");
    action.setCallback(this, function(actionResult) {
        var infos = actionResult.getReturnValue();
        component.set("v.recordTypes", infos);
    });
    $A.enqueueAction(action);
  }

})

Note :

This force:createRecord event is handled by the one.app container.It's supported in Lightning Experience and salesforce1 only.This event presents a standard page to create a record.

Lightning:recordForm


"Lightning:recordForm" which suppresses using "lightning:recordEditForm and lightning:recordViewForm" separately to handle record view and edit.

"lightning:recordForm" is very powerful component for editing,viewing and adding
a record in lightning.

<aura:attribute name="fieldArray" type="String[]"
default="['Name','Email','Phone','AccountId']"/>

<lightning:recordForm aura:id="recordForm"
recordId="{!v.recordId}"
objectApiName="contact"
fields="{!v.fieldArray}"/>

Note : "ObjectApiName" is always required while using lightning:recordForm component.

Lightning Component Facets


A facet attribute is similar to any other component attributes,but instead of having a
primitive,collection,sObject or custom class type,it has an "Aura.Component[]" type.
And instead of holding those kind of data,it will hold HTML markups or even another
component.

Note :
A facet is implicitly defined in each component, the body facet.When we reference a subcomponent
writing some HTML markups between the tags that include the component into the container,
we are implicitly setting the body facet.

ex :

<!-- <c:SubComponent> -->


<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    <aura:attribute name="topArea" type="Aura.Component[]"/>
    <aura:attribute name="leftArea" type="Aura.Component[]"/>
    <aura:attribute name="rightArea" type="Aura.Component[]"/>
    <aura:attribute name="bottomArea" type="Aura.Component[]"/>
    <div class="mytop">
        {!v.topArea}
    </div>
    <div class="mymiddle">
        <div class="myleft">
            {!v.leftArea}
        </div>
        <div class="myright">
            {!v.rightArea}
        </div>
    </div>   
    <div>
        I am the body!: {!v.body}
    </div>
     <div class="mybottom">
        {!v.bottomArea}
    </div>
</aura:component>

<!--<c:BottomComponent/> -->

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<p>Bottom Area Component html text</p>
</aura:component>

<!--<c:ParentContainer/> -->

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    <c:SubComponent>
    <aura:set attribute="topArea">
        <h1>Top Area component</h1>
    </aura:set>
    <aura:set attribute="leftArea">
        <ul>
            <li>Left area app</li> 
            <li>Left area Menu</li> 
            <li>left area App Builder</li> 
        </ul>
    </aura:set>
    <aura:set attribute="rightArea">
            <p>Right area !</p>
        </aura:set>
        <aura:set attribute="bottomArea">
           <c:BottomComponent></c:BottomComponent>
        </aura:set>
    </c:SubComponent>
</aura:component>

Sunday, 26 August 2018

State Management In Batch Apex in Salesforce

State Management In Batch Apex in Salesforce


Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000 records and is executed without the optional scope parameter is considered five transactions of 200 records each.

If you specify Database.Stateful in the class definition, you can maintain state across these transactions. This is useful for counting or summarizing records as they're processed. For example, suppose your job processed opportunity records. You could define a method in execute to aggregate totals of the opportunity amounts as they were processed.
If you do not specify Database.Stateful, all member variables in the interface methods are set back to their original values.
The following example summarizes a custom field total__c as the records are processed:

global class SummarizeAccountTotal implements Database.Batchable<sObject>, Database.Stateful{
global final String Query;
global integer Summary;
global SummarizeAccountTotal(String q){Query=q;
Summary = 0;
}

global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<sObject> scope){
for(sObject s : scope){Summary = Integer.valueOf(s.get('total__c'))+Summary;

}
}

global void finish(Database.BatchableContext BC){

}
}

Database.Callouts

Database.Allowscallouts allows us to use a callout in batch Apex.Callouts include HTTP
requests as well as methods defined with the webservice keyword.

How to make webservice callout from scheduler

scenario-1 : if scheduler doesn't depends on Batch or Queueable(depends on future methods)
scenario-2 : If Scheduler depends on Batch
scenario-3 : If Scheduler depends on Queueable

Note :
if we try to make a call from scheduler,we will get the below exception:

system.calloutException: callout form scheduled Apex not supported

Reason : All we know that we cannot schedule a class which contains callout.
The only solution for this is to use @future annotation to enforce(for Normal apex classes)
but we cannot process future methods inside batch.

Scenario -1 :
if scheduler doesn't depends on Batch or queueable

ex :

//Scheduled Apex
public class DemoScheduler1 implements Schedulable{
    public void execute(SchedulableContext sc){
        system.debug('*******Going to call future method ');
        DemoAsynchronousTest.futureMethodCallFromScheduler();
    }
}
//apex class containing future method
public class DemoAsynchronousTest{
    @future
    public static void futureMethodCallFromScheduler(){
        system.debug('******futureMethodCallFromScheduler get called');
    }
   
}

Scenario -2 :
if scheduler depends on Batch

ex :

public class ExampleScheduler implements Schedulable, Database.AllowsCallouts, Database.Batchable<sObject> {
 
    public void execute(SchedulableContext SC) {
      Database.executebatch(new ExampleScheduler());
   }
 
 public Iterable<sObject> start(Database.Batchablecontext BC){
        ExampleHelper.makeWebserviceCallout();
     return null;   
 }

    public void execute(Database.BatchableContext BC, List<sObject> scope){     
    }

  public void finish(Database.BatchableContext info){
       
    }
}

public class ExampleHelper{

  public static void makeWebserviceCallout(){
  HttpRequest req = new HttpRequest();
  req.setEndpoint('http://www.yahoo.com');
  req.setMethod('GET');
  String username = 'myname';
  String password = 'mypwd';
 
  Blob headerValue = Blob.valueOf(username + ':' + password);
  String authorizationHeader = 'BASIC ' +
  EncodingUtil.base64Encode(headerValue);
  req.setHeader('Authorization', authorizationHeader);
   
  // Create a new http object to send the request object
  // A response object is generated as a result of the request 
 
  Http http = new Http();
  HTTPResponse res = http.send(req);
  System.debug(res.getBody());
 }
}

Scenario-3 :
if scheduler depends on queueable

public class ExampleScheduler implements Schedulable{
 
    public void execute(SchedulableContext SC) {
      System.enqueueJob(new ExampleQueueable());
   }
}

public class ExampleQueueable implements Queueable, Database.AllowsCallouts {

    public void execute(QueueableContext context) {
        ExampleHelper.makeWebserviceCallout();
    }
}

or

global class SampleCalloutCls implements Queueable, Schedulable, Database.AllowsCallouts{
    //variable declaration
    private List<Account> accountList ;

//Queueable interface method 
    public void execute(QueueableContext QC){
        // Perform callout here to get the accounts from external system.       
        //Calling batch process if list contains records.
        if(!accountList.isEmpty()){
           Database.executeBatch(new SampleBatchCls(accountList));
        }
    }

//Method to Schedule the current class
   global void execute(SchedulableContext sc) {
      system.enqueueJob(new SampleCalloutCls()); 
   }

 }
//End of class

Thursday, 23 August 2018

Differences between Enterprise and Parter WSDL

Enterprise WSDL
1.Is strongly typed
2.Contains the metadata about all standard and custom fields and objects
3.Can only be used against your Salesforce instance
Partner WSDL
1.Is loosely typed
2.Takes an array of key-value pairs
3.Does not contain metadata about objects and fields
4.Can be used against many Salesforce.com organizations

Wednesday, 22 August 2018

Different messages in visualforce

<apex:messages> :
==================

This component is used to display warning or error message for a specific component.

Note :
it is used to display an error on only a very specific field.it is used to allow the developer to place field specific errors in a specific location.

ex :

<apex:message for="phone" />
<apex:inputText value={!Phone} label="Phone"
id="Phone" />


<apex:messages> :
================
This component display all the error messages.These errors are displayed as a list with no
styling.

ex :
<apex:messages />
<apex:inputText value={!Phone} label="Phone"
id="Phone" />
<apex:inputText value={!DOB} label="DOB"
id="dob" />

<apex:PageMessages> :
======================

This Component provides the salesforce styling for the messages.

it is used to display all of the messages on a page. it will display salesforce generated messages as well as custom messages added to the apex class.

ex :
 <apex:pageMessages />
<apex:input value="{!Jdate}" label="DOB" type="date" id="dob" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"  />

<apex:pageMessage> :
=====================
This component is used to display custom messages with severity error,warning etc
in the VF Page.

it is used to display a single custom message using the salesforce formatting.you can specify the severity and the strength

ex :
<apex:pageMessage summary="This is page message"  severity="warning" strength="3" />
<apex:input value="{!Jdate}" label="DOB" type="date" id="dob" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"  />

Note :

apex:pageMessages shows all of the errors with formatting,apex:pageMessage only shows
the specified message.

Action tags in salesforce

Action tags support for calling action and refresh the field only not visualforce page.

Action Function :
===================
Action Function is used in the visualforce page to call the service side method using javascript and does not add the Ajax Request before calling the Controller method.

ex :
<apex:actionFunction name=”myactionfun”
action=”{!actionFunctionTest}”
reRender=”pgBlock, pbSection” />

Action Support :
================
As the name indicates action support is used to provide the support to the input field where we can not get event either manually or external event.It adds the AJAX request to visualforce Page and then calls the controller method.

<apex:inputText value=”{!dummyString}” >
                      <apex:actionSupport event=”onchange” action=”{!actionSupportTest}”                                     reRender=”pgBlock, pbSection” />
</apex:inputText>

Action Poller :
================
A timer that sends an AJAX request to the server according to a time interval that
you specify.Each request can result in a full or partial page update.

ex :

<apex:actionPoller action=”{!incrementCounter}” reRender=”counter” interval=”15″ enabled = “true” />

Action Region :
===============
Action Region use AJAX functionality to update partial page.

ex :

<apex:page controller="ActionRegionCLS" >
 <apex:pagemessages id="msgs"></apex:pagemessages>
 <apex:form >
  <apex:pageblock id="pb">
   <table>
     <apex:actionRegion >
      <tr>
        <td> <apex:outputLabel value="Enter Account Number"> </apex:outputLabel> </td>
        <td>             
          <apex:inputtext value="{!reqAccNumber}"/>
          <apex:commandButton value="Retrive" action="{!fillRecord}" rerender="pb,msgs"/>
          </td>
       </tr> 
     </apex:actionRegion>
     <tr>
      <td> <apex:outputLabel value="Account Name"> </apex:outputLabel> </td>
      <td>
        <apex:inputField value="{!accObj.Name}"/>
      </td>
     </tr>
     <tr>
     <td> <apex:outputLabel value="Account Type"> </apex:outputLabel> </td>
      <td>  <apex:inputField value="{!accObj.Type}"/> </td>
     </tr>
   </table>
  </apex:pageblock>
 </apex:form>
</apex:page>

public class ActionRegionCLS{
 public String reqAccNumber{get;set;}
 public Account accObj{get;set;}

 public ActionRegionCLS(){
  accObj = new Account();
 }
 public void fillRecord(){
  if(reqAccNumber !=null && reqAccNumber !=''){
    List<Account> accLst = new List<Account>();
    accLst = [select id,Name,AccountNumber,Type,AnnualRevenue from Account where AccountNumber =:reqAccNumber];
    if(accLst !=null && accLst.size()>0){
     accObj = accLst[0];
    }
    else{
 
     ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.Info,' No Records found with this Account Number:'+reqAccNumber);
     ApexPages.addMessage(myMsg);
     accObj  = null;
 
    }
  }
 }

 }

Action status :
===============

A component that displays the status of an AJAX update request.An AJAX request can
either be in progress or complete.

ex :

<apex:actionStatus id="statusSaveTrip" stopText="">
    <apex:facet name="start">
        <div>
            <div class="popupBackground" />
            <div class="PopupPanel">
                <table border="0" width="100%" height="100%">
                    <tr>
                        <td align="center"><b>Please Wait</b></td>
                    </tr>
                    <tr>
                        <td align="center"><img src="{!$Resource.AJAXProgressBar}"/></td>
                    </tr>
                </table>
            </div>
        </div>
    </apex:facet>
</apex:actionStatus>

Note :

1.actionStatus: used to display start and stop statuses of AJAX requests.
2.actionSupport: used to call a second component when an event happens to the first component.
3.actionPoller: similar to actionSupport, but the event is based on a timer instead of a user action.
4.actionFunction: provides support for invoking a controller action from JavaScript code using an AJAX request by defining a new JavaScript function.
5.actionRegion: used to demarcate which parts of the page the server should reprocess.

what is visualforce view state ?

Visualforce pages that contain a form component also contain an encrypted,hidden form field that encapsulates the view state of the page.The view state is automatically created,and as its name
suggests,it holds the state of the page- state that includes the components,field values and controller state.

1.Minimize number of form on a page.Use apex:actionRegion instead of using 2 or more forms.

2.Refine your SOQL to only retrieve the data needed by the page.

3.All Public and private data members present in standard,custom and controller extensions
are saved.
4.The trasient variables are not passed to view state and therefore not saved in view state.

Note :
The transient keyword prevents the data  from being saved into the view state.This should be used for very temporary variables.

Maximum view state size limit is 135KB

Tips on reducing view state size :
===================================

1.Declare a variable as Trasient if possible.
2.Declare variable as static, as it is not saved in view state.
3.if you want to manage your own state, instead of using <apex:form> use HTML<form>
tag instead.
4.Recreate state instead of saving in view state.means if you can use SOQL instead of saving in some object or list,use it.
5.You can also use web service call, Ajax remoting to recreate state instead of saving in object.

Saturday, 18 August 2018

Difference between StandardController and StandardSetController?


ApexPages.StandardController encapsulates just a single Sobject (e.g. Account, Opportunity).

ApexPages.StandardSetController contains a list of records (one or more), and has additional functions to facilitate pagination (moving between pages)
and updating a number of records at once.

For example in test class when we initialize

ApexPages.StandardController

Account objAccount = [SELECT Name FROM Account LIMIT 1];
ApexPages.StandardController standctrl = new ApexPages.StandardController(objAccount );


ApexPages.StandardSetController

List<account> accountList = [SELECT Name FROM Account LIMIT 20];
ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(accountList);

Remote Action in salesforce

Remote action function in salesforce allows user to access any method from any class
through javascript methods, and get the result as a javascript object for further manipulation.

points to remember while implementing remote action function :

1.Remote action method should have @RemoteAction annotation.
2.The method should also be Global and static.

ex :

global with sharing class AccountRemoteActionController {

    public String accountName { get; set; }
    public static Account account { get; set; }
    //Default Constructor..
    public AccountRemoteActionController() {
   
    }
   
    @RemoteAction
    global static Account getAccount(String accountName)
    {
        account = [select id, Name from Account where Name = :accountName LIMIT 1 ];
        return account;
    }
}



<apex:page docType="html-5.0" controller="AccountRemoteActionController"> 
    <apex:form>
         <script type="text/javascript">
    function getAccountJS()
    {
        // get the value and save in variable
    var varAccName=document.getElementById('MyAccountName').value;
     
        // check account name enetered or not
      if(varAccName=='' || varAccName==null)
        {
         alert('Please enter account name');
        }
        else
            {
           AccountRemoteActionController.getAccount( varAccName,function(result,event)
                                                    {
                                                   
                                                    if(event.status)
                                                        {
                 document.getElementById("{!$Component.TheAccontBlock.TheAccountPageBlockSection.TheFirstItem.accID}").innerHTML = result.Id;
                document.getElementById("{!$Component.TheAccontBlock.TheAccountPageBlockSection.TheSecondItem.accName}").innerHTML = result.Name;
                                                                                           
                                                        }
else if(event.type='exception')
    {
    document.getElementById("error-js").innerHTML = event.message;
    }
     else
         {
          document.getElementById("error-js").innerHTML ='No Account Record Found';
         }                                                   
    },{escape:true});
           
            }
    }
    </script>
        Enter Account Name   <input type="text" id="MyAccountName"/>
        <button id="btnGetAccount" onclick="getAccountJS()">Get Account Name           
        </button>
        <div id="error-js">           
        </div>
        <apex:pageBlock id="TheAccontBlock">
        <apex:pageBlockSection id="TheAccountPageBlockSection" columns="2">
            <apex:pageBlockSectionItem id="TheFirstItem">
               <apex:outputText id="accID"></apex:outputText>
            </apex:pageBlockSectionItem>
             <apex:pageBlockSectionItem id="TheSecondItem">
                 <apex:outputText id="accName"></apex:outputText>
            </apex:pageBlockSectionItem>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form> 
</apex:page>


global with sharing class OpportunityRemoteActionController {
      public Opportunity opp{get;set;}
      public String stageName{get;set;} 

      public OpportunityRemoteActionController() {
         
      }
       
      public List<SelectOption> getOptions() {
          List<SelectOption> options = new List<SelectOption>();
          Schema.DescribeFieldResult fieldResult = Opportunity.StageName.getDescribe();
          List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
          options.add(new SelectOption('--Select--', '--Select--'));
         for( Schema.PicklistEntry f : ple)
         {       
          options.add(new SelectOption(f.getLabel(), f.getValue()));
         } 
         return options;
      }     

      @RemoteAction
      global static List<Opportunity> getOpportunityDetails(String stageNameDet) {       
             List<Opportunity> opp= [select id,Name,Amount,stageName from Opportunity WHERE stageName =: stageNameDet];       
          return opp;
      }

}


<apex:page controller="OpportunityRemoteActionController" >
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
function getStageJS(){
 var oppStage= document.getElementById("{!$Component.theFm.oppStage}").value; 
  OpportunityRemoteActionController.getOpportunityDetails( oppStage,
    function(result, event){   
         var html = '<table with="100%" border="thick solid">';
          html = html + '<caption><b>Opportunity Details</b></caption><tr></tr>';
          html = html + '<tr><th>Opportunity Name</th>';
          html = html + '<th>Amount</th> </tr>';
         if (event.status && event.result) {                 
          for (var prop in event.result) {         
          html = html + '<tr><td>'+event.result[prop].Name+'</td> <td>'+event.result[prop].Amount+'</td></tr> ';
      }     
       html = html + '</table>';   
            $("#opportunityDetails").html(html);
           
      } else {
             alert(event.message);
      }

}, {escape:true});
}
 </script>
   <div align="center" width="550px">
      <apex:form id="theFm">
        <apex:selectList value="{!stageName}" size="1" id="oppStage" onchange="getStageJS()">
         <apex:selectOptions value="{!options}"/>
         </apex:selectList>
      </apex:form>
   </div>
   <br/>
   <br/>
   <div id="opportunityDetails" align="center">
         <!-- Opportunity details is displayed here. -->
   </div>
</apex:page>

Getter and Setter methods in Apex

Getter and setter methods are used to pass data from your visualforce page to your controller and vice versa.

The "get" method is used to pass data from your apex code to your visualforce page.

The set method is used to pass values from your visualforce page to the controller.


ex :

public class simplegetset {
    public String userinput {get;set;}
    public String getuserinput()
    {
        return 'John';
    }
 
    public void setuserinput(String userinput)
    {
        this.userinput = userinput;
    }
}


<apex:page controller="simplegetset" >
    <apex:form>
    <apex:outputlabel value="Enter your name here"/>
       <apex:inputtext value="{!userinput}">
           <apex:actionsupport event="onchange" rerender="display" />
       </apex:inputtext>                 
    <apex:outputpanel id="display">
        <apex:outputtext value="The name entered is {!userinput}"/>
    </apex:outputpanel>                 
  </apex:form>
</apex:page>


Visualforce requires a "getter" and "setter" to reference a variable in the controller or extension. Without a getter or setter, even public or global variables cannot be referenced in Visualforce expressions.

"get;" is basically: public *datatype* getVarName() { return varName; }

"set;" is basically: public void setVarName(*datatype* value) { varName = value; }

Wednesday, 15 August 2018

what is the Recursive trigger and how to handle it?

Trigger when called over and over then its called recursive trigger.Below error will be display
if not controlled.

error message : maximum trigger depth exceeded

ex : Recursive code

Trigger AccountTrigger on Account(before insert)
{
    insert new Account(Name='test');

}

How to stop it ?

In order to avoid the situation of the recursive call,make sure your trigger is getting executed only one time.To do so, you can create a class with a static Boolean variable with default value true.

In the trigger,before executing your code keep a check that the variable is true or not.once you check,make a variable false.

ex :

public class checkRecursive
{

  private static boolean run=true;

  public static boolean runOnce()
  {
     if(run){
         run=false;
        return true;
      }
      else
       {
         return run;
       }

  }

}

Trigger AccountTrigger on Account(before insert)
{

    if(checkRecursive.runonce())
      {
        insert new Account(Name='test');
      }

}

After executing workflow rules again before trigger and after triggers will execute,how can you avoid?

class :
==========

global class validator_cls
{

 private static boolean blnAlreadyDone=false;

 public static boolean hasAlreadyDone()
  {
     return blnAlreadyDone;
  }

 public static boolean hasAlreadyDone()
  {
     blnAlreadyDone=true;
  }


}

Class :
============


public class AccountTriggerHandler
{

 public void OnBeforeInsert(Account[] newaccounts)
 {
   if(!validator_cls.hasAlreayDone)
     {

        AddUpdateFields(newAccounts);
        validator_cls.setAlreadyDone();
     }

 }


}

Trigger :
==============

Trigger AccountTrigger on Account(before insert,after insert,before update,after update)
{

AccountTriggerHandler handler=new AccountTriggerHandler();

/* Before Insert */

 if(Trigger.isBefore && Trigger.isInsert)
  {
    handler.OnBeforeInsert(Trigger.new);
  }
/* After Insert */
  else if(Trigger.isAfter && Trigger.isInsert)
  {
     handler.onAfterInsert(Trigger.new);
  }
/* Before Update */
  else if(Trigger.isBefore && Trigger.isUpdate)
  {
    handler.onBeforeUpdate(Trigger.old,Trigger.new,Trigger.newMap);
  }
/* After Update */
  else if(Trigger.isAfter && Trigger.isUpdate)
  {
    handler.onAfterUpdate(Trigger.old,Trigger.new,Trigger.newmap);
  }
/* Before Delete */
  else if(Trigger.isBefore && Trigger.isDelete)
  {
    handler.onBeforeDelete(Trigger.old,Trigger.oldmap);
  }
/* After Delete */
  else if(Trigger.isAfter && Trigger.isDelete)
  {
    handler.OnAfterDelete(Trigger.old,Trigger.oldmap);
  }
  else if(Trigger.isUnDelete)
  {
    handler.onUndelete(Trigger.new);
  }

}

Roll up summary functionality through trigger

public class SampleRollupSummary {
 
    public static void rollupContacts(list<contact> lstOfconts){
        system.debug('==lstOfconts== : '+lstOfconts);
        set<id> accIds = new set<id>();
        list<account> updLstOfAccs = new list<account>();
        list<contact> lstCons = new list<contact>();
     
        for(contact con : lstOfconts){
            accIds.add(con.accountid);
        }
        system.debug('==accIds==:'+accIds);
        list<account> lstAccs = [select id,name,Total_Count__c, (select id from contacts) from account where id in : accIds];
     
        for(account acc : lstAccs){
            system.debug('==acc.contacts.size()=='+acc.contacts.size());
            acc.Total_Count__c = acc.contacts.size();
            updLstOfAccs.add(acc);
        }
        if(updLstOfAccs.size() > 0){
            update updLstOfAccs;
        }     
     
    }
 
}


trigger RollupSummaryTriggerOnAccountObj on contact(after insert, after update, after delete, after undelete) {
    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
        SampleRollupSummary.rollupContacts(trigger.new);
    }
    else if (trigger.isAfter && trigger.isDelete) {
        SampleRollupSummary.rollupContacts(trigger.old);
    }
}

Salesforce Governer Limits

1.DML Governing Limits

we can have only 150 DML statements with in a transaction.

we rectify this type of errors by using bulky operations. put similar operation on the object in list and invoke the DML on the list.

2.SOQL Governing Limits

with in a transaction we can write only 100 SOQL queries.

use
Map<Id,Account> accMap=new map<Id,Account>([select id,Name from Account]);

3.DML rows Limit :

Number of DML rows : 10000

4.SOSL Governing Limits :

Number of SOSL queries : 20

5.Maximum CPU time : 10000
6.Maximum heap size : 6000000
7.Number of callouts : 100
8.Number of Email Invocation : 10
9.Number of future calls : 50
10.Number of queueable jobs added to the queue:50
11.Number of mobile apex push calls :10
12.Number of query rows : 50000

DML statements vs Database class Methods


Apex offers two ways to perform DML operations

1.Using DML statements
2.Database class methods

Difference between the two options that by using the Database class method.

You can specify whether or not to allow for partial record processing if errors are encountered.

you can do so by passing an additional second Boolean parameters.

if you specify FALSE for this parameter and if a record fails,the remainder of DML
operations can still succeed.

 ex : Database.insert(accList,false);

False : partial processing allowed
True  : partial processing not allowed

By default this optional parameter is true,which means that if at least one sObject can't be processed,all remaining sObjects won't and an exception will be thrown for the record that causes a failure.

Order of execution of apex code

1. Before triggers:
     If we update child records in before triggers then parent record automatically update.
2. Validation rules:
 If validation matches the criteria then error will populate in same page.
Runs most system validation steps again, such as verifying that all required fields have a non-null value, and runs any user-defined validation rules. The only system validation that Salesforce does not run a second time (when the request comes from a standard UI edit page) is the enforcement of layout-specific rules.
*Note: Saves the record to the database, but does not commit yet.

3. After Triggers:
4. Assignment Rules:
5. Auto Response Rules:
6. Workflow Rules:
If there are workflow field updates, updates the record again.
7. Escalation Rules:
       If the record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Parent record goes through save procedure.
     If the parent record is updated, and a grand-parent record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Grand-parent record goes through save procedure.
Executes Criteria Based Sharing evaluation.
Commits all DML operations to the database.

8.Executes post-commit logic, such as sending emails



simple steps:
==============
Order of Events
  1. Original record is loaded or new record is initialized
  2. Fields values are loaded into sObjects
  3. System validations rules are executed:
  4. Before triggers are executed
  5. System validations rules are run again and custom validation rules are checked.
  6. Duplicate rules are executed
  7. Record is saved but not committed
  8. After triggers are executed
  9. Assignment rules are executed
  10. Auto-response rules are executed
  11. Workflow rules are executed
  12. Before triggers,system validation rules and after triggers are executed due to workflow field updates
  13. Processes are executed
  14. Escalation rules are executed
  15. Entitlement rules are executed
  16. Rull-up summary fields and cross-object formula fields are updated
  17. Updated parent and grand parent records are saved
  18. Criteria based sharing rules are evaluated
  19. DML operations are committed to the database
  20. Post-commit logic is executed

Apex Basics

Apex is a strongly typed,object -oriented programming language that allows developers
to execute flow and transaction control statements on the Force.com platform.

Apex enables developers to add business logic to most system events,including button clicks,
related record updates and visualforce pages.

Data Types :
============
1.primitives
2.sObjects
3.Collections

Apex primitive data types include :

1.Boolean : can only be assigned true,false or null
2.Decimal : A number that includes a decimal points.
3.Double : A 64-bit number that includes a decimal point
4.ID : Any Valid salesforce.com ID
5.Integer : A 32bit number that does not include a decimal point.
6.Long : A 64-bit number that does not include a decimal point.
7.String : Any set of characters surrounded by single quotes.
8.Date : A value that indicates a particular day.
9.DateTime : A value that indicates a particular day and time
10.Time : A value that indicates a particular time.

sObjects :
=============
the term sObject refers to any object that can be stored in the Force.com platform database.

An sObject variable represents a row of data and can only be declared in Apex.

ex :
Contact c= new Contact(FirstName='raj';LastName='kiran';
Email ='test@gmail.com');

Account a =new Account(Name='TCS');
insert a;

Account a1=[select Name from Account
where ID='857598jh'];
a1.Name='new  Name';
update a1;

Collection :
============
collection of primitives or sObjects.

A LIST is an ordered collection.so use
list when you wnat to identify list element
based on INDEX NUMBER.
List can contain duplicates.

List<string> colors =new List<string>('red','purple','green');

List<Account> accts=[select Name,Type from Account
where Industry='Energy'];

List<Contact> email_contacts=
[select FirstName,LastName from Contact where
Email!=Null];

1. Set
2. List
3. Map

A set is a collection of unique,unordered elements.it can contain primitive data types or sObjects.

A set is an unordered collection of primitives or sObjects that do not contain any duplicate elements.so use SET if you want to make sure that your collection should not conatin Duplicates.

ex :
Set<String> s = new Set<String>();
Set<String> s = new Set<String>{'Jon', 'Quinton', 'Reid'};

commonly you'll see developers construct a set of IDs from a query,trigger context,etc.
and the use it as part of WHERE clause in their SOQL query.

ex :

Set<ID> ids = new Set<ID>{'0017000000cBlbwAAC','0017000000cBXCWAA4'};
List<Account> accounts = [Select Name From Account Where Id = :ids];


Map :
=====
A MAP is a collection of key-value pairs where each unique key maps to a single value.
Keys can be any primitive data type,while values can be a primitive,sObject,Collection
types or an Apex Object.

Use a map when you want to quickly find something by a key.Each key must be unique
but you can have duplicate values in your MAP.

Map<Integer, String> m = new Map<Integer, String>{5 => 'Jon', 6 => 'Quinton', 1 => 'Reid'};
Map<ID, Set<String>> m = new Map<ID, Set<String>>();
// creates a map where the key is the ID of the record
Map<Id,Account> aMap = new Map<Id, Account>([Select Id, Name From Account LIMIT 2]);


Tuesday, 14 August 2018

Triggers in Salesforce


Trigger is piece of code that is executes before and after record is Insert/update/Deleted from the force.com database.

There are two types of Triggers:

1.Before trigger are used to update or validate record values before they're saved to the
database.

2.After triggers are used to access field values that are set by the system and to effect changes in other records.The records that fire the after trigger are read-only.

syntax:
========

trigger triggerName on ObjectName(trigger_events)
{

  //code_block

}

where trigger_events can be a comma-separated list of one or more of the following events :

before insert
before update
before delete
after insert
after update
after delete
after undelete

ex :
========
check email null or not before insert update
record


trigger CheckEmail on contact(before Insert,before update)
{
   for(Contact c:Trigger.new)
   {
     if(c.Email ==Null)
      {
        c.Email.addError('Please insert Emil ID);
      }
   } 
}

Trigger Context Variables :
=====================
All triggers define implicit variables that allow developers to access run-time context.


Trigger.isInsert : Returns true if this trigger was fired due to an insert operation.

Trigger.isUpdate : Returns true if this trigger was fired due to an update operation

Trigger.isDelete : Returns true if this trigger was fired due to delete operation.

Trigger.isBefore : Returns true if this trigger was fired before any record was saved.

Trigger.isAfter : Returns true if this trigger was fired after all records were saved.

Trigger.isUndelete : Returns true if this trigger was fired after a record is recovered from the
Recycle Bin.

Trigger.new : Returns a list of the new versions of the sObject records.Note that this sObject list
is only available in insert and update triggers,and the records can only be modified
in before triggers.

Trigger.newMap : A map of IDs to the new versions of the sObject records.Note that this map
is only available in before update,after insert and after update triggers.

Trigger.old : Returns a list of the old versions of the sObject records.Note that this sObject
list is only available in update and delete triggers.

Trigger.oldMap : A map of IDs to the old versions of the sObject records.Note that this map
is only available in update and delete triggers.

Trigger.size: The total number of records in a trigger invocation,both old and new.

Trigger.isExecuting : Returns true if the current apex code is a trigger.


ex :


trigger Opportunity_trigger on Opportunity(before insert,before update){

  for(Opportunity p : Trigger.new)
  {
    if(Trigger.isInsert && p.amount<10000)
      {
       p.addError("amount is less than 10000');
      }
    else if(Trigger.IsUpdate && p.Amount<20000)
         {
           p.addError('Amount is less than 20000');
         }

  }

}

ex :

  public class trigger_class{
    public static void trigger_method(List<Opportunity> oppt){

        Double Total_amount=0;
      for(Opportunity o : Select Amount from opportunity where createddate=Today()
                               and CreatedById= : UserInfo.getUserID()]){
         
           Total_amount=Total_Amount +o.Amount;
       
           }

        for(Opportunity o1 : oppt){
         
           Total_amount=Total_Amount +o1.Amount;
       
              if(Total_amount>100000)
                {
                  01.addError('you have exceeded your daily limit');
                }
            }

    }

  }


trigger t1 on Opportunity(before Insert){
trigger_class.trigger_method(Trigger.new);
}

Transaction Control using Database savepoint and rollback in Apex

SavePoint and Rollback will help us to maintain transaction for DML statement.

suppose you have written multiple lines of DML statements in a try block,if any error
occurs during DML Operations,the operation will be rolled back to the most recent
save point and the entire tranasction will not be aborted.

ex :

savepoint sp=Database.setsavepoint();

try
{
// create account

Account a=new Account();
a.Name='Test';
insert a;

// create contact

Contact c=new contact();
a.accountid=a.id;
insert c;

}
catch(DMLException exc)
{

Database.rollback(sp);

}

In this example, if any error occurs while inserting the Account ‘a’ or Contact ‘c’, then the entire transaction will be rolled back to SavePoint ‘sp’, as specified in the catch section by Database.

Friday, 27 July 2018

Relationships available in Salesforce

A relationship is an association among the objects. We can categorize the relationships into three kinds
1. One-to-One, 2. One-to-Many, and 3. Many-to-Many. But Salesforce supports only One-to-Many relationship in 2 flavors among the sObjects.
Salesforce offers One-to-Many relationship as following types,
1. Master-Detail relationship
2. Lookup relationship

In addition to those, Salesforce offers two more Special relationships called Self relationship, and Hierarchical relationships.

Though, Salesforce doesn't offer Many-to-Many relationship, we can achieve this using two One-to-Many relationships(We discuss it later).

1. Master-Detail relationship
            An association which tightly couples the Parent(Master) object and Child(Detail)  object [and Sub Detail object] is called Master-Detail relationship. What does Tight coupling means is,
     i. When a record in Parent is deleted, the corresponding related record in the Child and Sub Detail 
        are also deleted (Cascading delete).
    ii. Security settings for the Child record are inherited from Parent i.e., the same security settings 
        specified for Parent are applied to Child records.
   iii. Records in Child objects don't have Owner field, as these records are tightly coupled with Parent 
        record. So the Custom objects on Detail and SubDetail side cannot have Sharing Rules, Manual 
       Sharing, and Queues which require Owner field.

By default we cannot reparent the records in Detail and SubDetail objects. If we want to allow Reparenting the Detail and SubDetail records, we should specify it when we defining the Master-Detail relationship by checking the "Allow Reparenting" checkbox.

Reparenting: Changing the Parent of a Child record is called Reparenting.
Ex: Suppose Parent object have ABC, XYZ records, and we created a child record for ABC record, changing the parent from ABC to XYZ in child object is called Reparenting. So the child record now associated with XYZ not ABC.

Roll-Up Summary fields:
      Fields which rolls up the data in child records are called Roll-Up summary fields. These are created on Parent object. We can roll up child's data in four ways, and we can apply roll up on all records or only a set of records that match the criteria you define.
          i. COUNT - counts the number of records that match a specific criteria or all records
         ii. SUM - Sum's up the data in child records which meet the specified condition or all records
        iii. MIN - returns the Minimum value among all records or specified records
        iv. MAX - return the Maximum value among all records or specified records

Other features:
   i. It is defined on Detail or SubDetail object
  ii. Master-Detail relationship is a required field, hence always included in Edit page of detail object.
 iii. Cannot be removed from page layout
 iv. At most two Master-Detail relationships are allowed per object
  v. Standard object cannot be at Detail side when Custom object is on Master side.

2. LookUp Relationship
        An association which loosely couples two objects (Parent and Child) or an Object to itself is called a LookUp relationship.
Loose Coupling: 
    i. No Cascading delete,
   ii. Parent and Child can have different security settings,
  iii. Child objects can have Sharing Rules, Manual Sharing, and Queues.

Differences between LookUp and Master-Detail relationship:
   i. LookUp relationship do not support Roll-Up summary fields
  ii. It is optional

Other features: 
  i. We can make a lookup field required on pagelayout,
 ii. We can make lookup field required when defining it,
iii. If the field is optional, you can specify one of the following 3 actions to occur when parent record
    is deleted.
     i). Clear the value in lookup field (default)
    ii). Don't allow deletion of lookup record that's part of lookup relationship,
   iii). Cascade delete (this is available only by contacting Salesforce, and also only if the custom
         object contains the lookup relationship, however the lookup object can be either Standard or 
         Custom).
 iv. We can create a maximum of 25 lookup relationship fields per object.

2.1 Self Relationship
        An association which binds the object to itself is called Self Relationship. A record in an object is linked  to another record in the same object.

2.2 Hierarchical Relationship
        An association which binds the object to itself is called Hierarchical Relationship.

Differences between Self and Hierarchical relationships are:
1. Self relationship can be used on any object,
2. Hierarchical relationship is only available for User object, to represent Employee-Manager
    association
3. In Self relationship, a record may reference itself indirectly, but in hierarchical a record should not
    reference itself directly or indirectly.

3. Many-to-Many relationship
        An association which binds two objects such a way that each record in two objects may have relationship with one or more records in other object.

      Salesforce supports this relationship through a Junction Object, which is defined as "a custom object with two master detail relationships to link two objects(custom or standard)".
Ex: Consider a situation where a Professor can teach many subjects and a Subject can be taught by many Professors.  So there exists a many-to-many relationship between Professor and Subject objects. To setup this association in Salesforce, we need to create an object called Teaches object. So the association looks like Professor-Teaches-Subject.

We know, the sharing and security settings are inherited from the parent to child in Master-Detail relationship, as we have two master detail relationships on Junction object, which master object settings are applied to junction object???

Primary Relationship: A master-detail relationship which is created first on the junction object.
Secondary Relationship: A master-detail relationship which is created second on the junction object.

The primary relationship determines the look and feel, Security and Sharing settings for the junction object. A master object to which the first relationship is created, junction object inherits that object settings. What happens if a Primary relationship is converted to a lookup or deleted??? automatically the secondary relationship becomes Primary Relationship, no manual effort required to make it Primary.