1. --------------
EMAIL TEMPLATE
--------------
1. When we are using Text Email Template then the body of template comes in the
"body" field of the template and can be replaced.
We will use "mail.setPlainTextBody(body)"
2. When we are using HTML Email Template then the body of template comes in the
"HtmlValue" field of the template and can be replaced.
We will use "mail.setHTMLBody(htmlvalue)"
3. If we are using "mail.setTemplateid" then we have to give
"setTargetObjectId". But reverse is not necessary.
4. TargetObjectId can only be the Id of Contacts, Leads & Users.
5. "setTemplateId" replaces "setSubject" & "setHTMLBody/setPlainTextBody".
"setTargetObjectId" replaces "settoAddresses".
----------------------------------
OPPORTUNITY & PRODUCT RELATIONSHIP
----------------------------------
1. Opp Line Item comes under Opportunity & PriceBookEntry.
2. Opp Line Item has look up to PriceBookEntry & PriceBookEntry has look upto
Product2 & PriceBook2.
---------------------------
TASK & PROFILE RELATIONSHIP
---------------------------
1. Task has look up to User.
2. User has look up to Profile.
3. For getting current Logged in User Information we use - UserInfo.getUserId();
4. For getting current logged in user profile information we use -
UserInfo.getProfileId();
--------------------------
PREVENT RECURSIVE TRIGGERS
--------------------------
1. Create a class with below code:
public class preventRepeat
{
public static boolean isRepeat=false;
}
2. In the Trigger implement this code:
if(!preventRepeat.isRepeat)
{
preventRepeat.isRepeat = true ;
//Trigger Body;
}
------------
2. MAP CONCEPTS
------------
1. Always use map when we have relationships: Lookup or Master-Detail.
2. When putting value in Map, Start For loop with Child/Detail object. In below
example: Master is ACCOUNT and Detail is OPPOTUNITY
for(Opportunity opp : lstopp)
{
if(map1.get(opp.accountId)==null)
{
map1.put(opp.accountId,new list<opportunity>());
}
map1.get(opp.accountId).add(opp);
}
3. Get Value from For Loop on Master object.
for(Account acc1 : trigger.new)
{
List<Opportunity> lstOpp1 = map1.get(acc1.Id);
for(Opportunity opp1 : lstOpp1)
{
if(opp1.CreatedDate > d)
{
Opp1.StageName = 'closed lost';
}
else
{
Opp1.StageName = 'closed Won';
}
lsttoupdate.add(opp1);
}
}
------------------
AGGREGATE FUNCTION
------------------
1. When we use AggregateResult we have to use "GROUP BY" clause.
for (AggregateResult results : [Select Account.id acc,Sum(Amount)amount
From Opportunity where accountId in:trigger.newmap.keyset() GROUP BY
Account.id])
{
system.debug(results );
ammountmap.put((ID)results.get('acc'),
(double)results.get('amount'));
}
2. Getting values from AggregateResult: (ID)results.get('acc') where ID is "Data
Type" and acc is "Alias"
------------------------
SEND ATTACHMENT IN EMAIL
------------------------
1. To create Attachment:
Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
3. efa.setFileName('email_pdf');
efa.setBody(b); //where b is "Blob"
2. To attach the attachment:
mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
-------------
SHARING RULES (STANDARD OBJECT)
-------------
1. Create instance for the sharing object. For example:
For Account --> Sharing object is "AccountShare"
1. AccountShare accshr = new AccountShare();
2. accshr.Accountid = acc.id; //where acc is any Account
Set the user or group id: accshr.UserOrGroupId = user1.id;
3. accshr.AccountAccessLevel= 'edit'; //Defining Account
accesslevel. It Can "Read" "Edit" "All"
4. accshr.OpportunityAccessLevel= 'edit'; //Defining child object
accesslevel. It Can "Read" "Edit" "None"
5. accshr.RowCause = Schema.AccountShare.RowCause.Manual;
/* Reason that this sharing entry exists. Read-only. There are many
possible values, including:
Manual Sharing—The User or Group has access because a User with
—All— access manually shared the Account with them.
Owner—The User is the owner of the Account or is in a Role above the
Account owner in the role hierarchy.
Sales Team—The User or Group has team access (is an
AccountTeamMember).
Sharing Rule—The User or Group has access via an Account sharing
rule. */
6. ATlast insert the sharing object i.e. insert "accshr";
-------------
SHARING RULES (CUSTOM OBJECT)
-------------
1. Instantiate the sharing object: Student__Share stuShr= new Student__Share
();
2. Set Parent ID: stuShr.ParentId = stu .Id;
3. Set the user or group id: stuShr.UserOrGroupId = user1.id;
4. Set access Level: stuShr.AccessLevel = 'edit';
5. Set Row Cause: stuShr.RowCause =
Schema.Student__Share.RowCause.Manual;
6. Insert object: insert stuShr;
-----------
BATCH CLASS
-----------
1. "Database.Batchable" interface is implemented.
global class class_name implements Database.Batchable<sObject> //Global
is access modifier & class_name is the name of Batch Class
2. There are three methods that are implemented in the batch class:
- START METHOD: global (Database.QueryLocator | Iterable<sObject>)
start(Database.BatchableContext bc)
4. {
//In this method data is queried from the database
on which operation is to be performed.
//Database.QueryLocator or Iterable<sObject> is
the return type of this method.
//QueryLocator bypasses the governor limit on the
number of records returned by SOQL.
}
- EXECUTE METHOD: global void execute(Database.BatchableContext BC,
list<sObject>)
{
//This method includes the operation that is being
performed through this batch class.
//Second arguement in this method is the List
which contains the records of the sObject or any other primitive data type.
}
- FINISH METHOD: global void finish(Database.BatchableContext BC)
{
//In this method we can perform any task such as
Sending a notification email that the job has been completed.
}
3. If we have to make any CALLOUT in our batch class then an additional
interface is also implemented:
global class class_name implements Database.Batchable<sObject>,
Database.AllowCallouts
4. Batch jobs are executed in a batch of 200. So any summary field is
recalculated in a new batch.
So if we want to keep track of any field or in other words we want to
maintain the state then an additional interface is implemented:
global class_name implements Database.Batchable<sObject>,
Database.Stateful
-----------------------------------------
EXAMPLE OF BATCH CLASS USING QUERYLOCATOR
-----------------------------------------
global class batch_Class implements Database.Batchable<sObject>
{
Global string query;
global batch_Class()
{
query = 'Select id,email from Student where Balance>0';
}
global Database.QueryLocator start(Database.BatchableContext bc)
{
Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<Student> stuList)
{
For(Student stu:stuList)
{
//Send Email Code
}
}
global void Finish(Database.BatchableContext bc)
5. {
}
}
---------------
SCHEDULER CLASS
---------------
1. "Schedulable" interface is implemented.
2. There is one method in this interface that is implemented in our scheduler
class.
- EXECUTE: global void execute(SchedulableContext sc){}
3. global class Scheduler_Class_Name implements Schedulable
{
global void execute(SchedulableContext SC)
{
Class_tobeScheduled obj = new Class_tobeScheduled();
}
}
4. Now "System.Schedule" method is called from the developer console with
following parameters:
Scheduler_Class_Name sch = new Scheduler_Class_Namee();
//Scheduler class is instantiated.
String str = '20 30 8 10 2 ?'; //('Seconds
Minutes Hours Day_of_Month Month Day_of_week Optional_Year')
system.schedule('Merge Job', str, sch); //('Scheduled
Job Name, Scheduled Period, Instance of Scheduler class')
5. Example: (* * 20 ? * ?) // It means that our class will run every
month at 20:00 hours
(* * 20 * * 2012) // It means that our class will run every day at
20:00 hours of 2012 year.
-----
NOTE:
-----
1. Never user DML operation in Trigger.new
2. Query the new records using any collection and then apply any DML on that
list.
6. {
}
}
---------------
SCHEDULER CLASS
---------------
1. "Schedulable" interface is implemented.
2. There is one method in this interface that is implemented in our scheduler
class.
- EXECUTE: global void execute(SchedulableContext sc){}
3. global class Scheduler_Class_Name implements Schedulable
{
global void execute(SchedulableContext SC)
{
Class_tobeScheduled obj = new Class_tobeScheduled();
}
}
4. Now "System.Schedule" method is called from the developer console with
following parameters:
Scheduler_Class_Name sch = new Scheduler_Class_Namee();
//Scheduler class is instantiated.
String str = '20 30 8 10 2 ?'; //('Seconds
Minutes Hours Day_of_Month Month Day_of_week Optional_Year')
system.schedule('Merge Job', str, sch); //('Scheduled
Job Name, Scheduled Period, Instance of Scheduler class')
5. Example: (* * 20 ? * ?) // It means that our class will run every
month at 20:00 hours
(* * 20 * * 2012) // It means that our class will run every day at
20:00 hours of 2012 year.
-----
NOTE:
-----
1. Never user DML operation in Trigger.new
2. Query the new records using any collection and then apply any DML on that
list.