Before Insert :
==================
Q::Which Trigger Context variables are allowed in before insert.
Ans :
-------------------------------------------------------------------------------
Trigger.New Trigger.NewMap Trigger.old Trigger.oldMap
--------------------------------------------------------------------------------
before insert Yes No No No
Q:: Which Operations are allowed on Trigger.New in before insert trigger
Ans:
Trigger.New
----------------------------
Read Write SOQL DML
----------------------------
Yes Yes No No
Scenario
==>>Basic Level Trigger scenario's on before insert
Scenario 1: When ever we are trying to insert new Account record with industry
as banking then Annualrevenue should be set as 50000;
Code :
trigger scenario1 on Account (before insert) {
for(Account a:Trigger.New){
if(a.industry=='Banking'){
a.annualRevenue=50000;
}
}
}
Test Class :
@isTest
private class Scenario1Test {
@isTest
static void test(){
Integer count=[select count() from Account];
Account a1=new Account(Name='aaa',Industry='Banking');
try{
insert a1;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
System.assertEquals(count+1,size);
Account acc=[select id, AnnualRevenue from Account where id=:a1.id];
System.assertEquals(acc.annualRevenue,50000);
}
}
Scneario 2: When ever new Account is creatd with out phone no it should throw
error message
Trigger :
trigger scenario2 on Account (before insert) {
for(Account a:Trigger.New){
if(a.phone=='' || a.phone==null){
a.addError('Phone no is a must ');
}
}
}
Test Class :
@isTest
private class scenario2 {
@isTest
static void testme(){
Integer count=[select count() from Account];
Account a=new Account(Name='aaa');
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
System.assertEquals(count,size);
}
}
Scneario 3:When ever new Application is created with Application Type as New
1. If pancard no is already existing in the black list then
set application status as rejected
2.If the pancard no is not available in black list set the application
status as pending
Solution:
Object :Application
Fields : Type : PicKList (New ,cancel,Block)
Status : PickList( Approved,Rejected,Pending)
Pancard: Text
Object: BlackList
Fields : Name : Text
Trigger Code:
trigger scenario3 on Application__c (before insert) {
List<String> pancards=new List<String>();
for(Application__c ap:Trigger.New){
if(ap.Type__c=='New')
pancards.add(ap.Pancard__c);
}
List<BlackList__c> black=[select id,Name from BlackList__c where name in :pancards];
Set<String> panList=new Set<string>();
if(black.size()!=0){
for(BlackList__c b:black){
panList.add(b.name);
}
}
for(Application__c a:Trigger.New){
if(panlist.contains(a.pancard__c)){
a.status__c='Rejected';
}else{
a.status__c='Pending';
}
}
}
Test Class :
@isTest
private class Scenario3 {
testmethod static void testme(){
BlackList__c b1=new BlackList__c();
b1.Name='1234';
insert b1;
Application__c ap1=new Application__c();
ap1.Applicant_Name__c='aaa';
ap1.Type__c='New';
ap1.Pancard__c='1234';
insert ap1;
Application__c res1=[select id,status__c from Application__c where id=:ap1.id];
System.assertEquals(res1.Status__c,'Rejected');
Application__c ap2=new Application__c();
ap2.Applicant_Name__c='aaa';
ap2.Type__c='Block';
ap2.Pancard__c='4567';
insert ap2;
Application__c res2=[select id,status__c from Application__c where id=:ap2.id];
System.assertEquals(res2.Status__c,'Pending');
Application__c ap3=new Application__c();
ap3.Applicant_Name__c='aaa';
ap3.Type__c='New';
ap3.Pancard__c='3456';
insert ap3;
Application__c res3=[select id,status__c from Application__c where id=:ap3.id];
System.assertEquals(res3.Status__c,'Pending');
}
}
Scenario 4: When ever new Account is created successfully corresponding contact
should be created using the details from Account
Trigger :
trigger scenario4 on Account (after insert) {
List<Contact> cons=new List<Contact>();
for(Account a:Trigger.New){
Contact c=new Contact();
c.lastname=a.name;
c.phone=a.phone;
c.accountid=a.id;
cons.add(c);
}
insert cons;
}
TestClass :
@isTest
private class scenario4Test {
@isTest(seealldata=true)
static void testme(){
Integer accCount=[select count() from Account];
Integer conCount=[select count() from Contact];
Account a=new Account(Name='aaa',Phone='123');
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer count=[select count() from Account];
Integer size=[select count() from Contact];
System.assertEquals(acccount+1,count);
System.assertEquals(conCount+1,size);
Contact con=[select accountid from Contact where accountid=:a.id];
System.assertEquals(con.lastname,a.name);
System.assertEquals(con.phone,a.phone);
System.assertEquals(con.accountid,a.id);
}
}
Scenario 5: When ever a new Opportunity is created .Then share that record with
user
Note : before you write the trigger
OWD: opporutnity :Private
Trigger:
trigger scenario5 on Opportunity (after insert) {
User u=[select id from User where alias='kshar'];
List<OpportunityShare> records=new List<opportunityShare>();
for(Opportunity op:Trigger.New){
OpportunityShare share=new OpportunityShare();
share.OpportunityId=op.id;
share.rowCause='Manual';
share.OpportunityAccessLevel='Edit';
share.UserOrGroupId=u.id;
records.add(share);
}
insert records;
}
____________________
__________________
trigger example on Application__c (before insert,after insert) {
if(Trigger.isInsert && Trigger.isBefore){
for(Application__c a:Trigger.New){
if(a.ID_Proof__c!='Pancard'){
a.Address_Proof__c=a.ID_Proof__c;
}
}
}
if(Trigger.isAfter && Trigger.isInsert){
List<Application__c> newList=[select CreditLimit__c,Salary__C from Application__c where id in:Trigger.New];
for(Application__c ap:newList){
if(ap.salary__c>50000){
ap.CreditLImit__c=3*ap.salary__C;
}else{
ap.CreditLImit__c=2*ap.salary__c;
}
}
update newList;
}
}
===========================================
Scenario 1: When ever a new Account record is inserted if the industry is
'Banking' set the annualrevenue as 50,00,000 before insert
Code :
trigger annualexample on Account (before insert) {
List<Account> accs=Trigger.New;
for(Account a:accs){
if(a.industry=='Banking')
a.annualRevenue=5000000;
}
}
Test Class :
@isTest
public class AnnualTest {
@isTest
static void testme(){
Integer count=[select count() from Account];
Account a1=new Account(Name='aaa',Industry='Banking');
Account a2=new Account(name='bbb',Industry='Energy');
try{
insert a1;
insert a2;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
System.assertEquals(size,count+2);
Account acc=[select annualrevenue from Account where id=:a1.id];
System.assertEquals(acc.annualRevenue,5000000);
Account acc1=[select annualrevenue from Account where id=:a2.id];
System.assertNotEquals(acc1.annualRevenue,a1.AnnualRevenue);
}
}
=====================================================================
Scenario 2:
Object : Account
Validation Rule : if the annualrevenue < 10,000 then throw error
Trigger :Create a before insert tigger on Account w which will modify the
annualrevenu of new records which we are inserting as 5,00,000
Code: trigger annualvalidation on Account (before insert) {
for(Account a:Trigger.New){
a.annualRevenue=500000;
}
}
Test Class :
@isTest
private class AnnualValidation {
@isTest
static void testme(){
Integer count=[select count() from Account];
Account a=new Account(Name='bbb',AnnualRevenue=900);
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
Account acc=[select annualRevenue from Account where id=:a.id];
System.assertEquals(size,count+1);
System.assertEquals(acc.annualRevenue,500000);
}
}
======================================================================
Scenario 3:
Object : Account
Trigger: After Insert
Description : When ever new Account record is successfully created then
create the corresponding contact record for the account
with
account name as contact lastname
account phone as contact phone
Trigger Code:
trigger accountAfter on Account (after insert) {
List<Contact> cons=new List<Contact>();
for(Account a: Trigger.New){
Contact c=new Contact();
c.accountid=a.id;
c.lastname=a.name;
c.phone=a.phone;
cons.add(c);
}
insert cons;
}
Test Class :
@isTest
private class AccountAfter {
@isTest
static void testme(){
Integer count=[select count() from Account];
Integer size=[select count() from Contact];
Account a=new Account(Name='Testing',phone='111');
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer newCount=[select count() from Account];
Integer newsize=[select count() from Contact];
Contact c=[select lastname,phone from Contact where accountid=:a.id];
System.assertEquals(c.lastname,a.name);
System.assertEquals(c.phone,a.phone);
}
}
Create a New Account Record and test it
====================================================================
Scenario :4
Object : Account
Trigger : before Update
When ever the phone no in the account record is modified
then fetch all the contacts of the account record and update the
contact otherphone no field value with account phone no field value;
Trigger Code:
trigger accountphone on Account (before update) {
List<ID> accs=new List<ID>();
Map<Id,Account> oldMap=Trigger.oldMap;
Map<Id,Account> newMap=Trigger.NewMap;
for(Id aid:oldMap.keySet()){
if(oldMap.get(aid).phone!=newMap.get(aid).phone)
accs.add(aid);
}
List<Contact> conList=[select otherphone,accountid from contact where accountid in:accs];
if(conList.size()>0){
for(contact c:conList){
c.otherphone=newMap.get(c.accountid).phone;
}
update conList;
}
}
Test Class :
@isTest
public class accountphone {
@isTest
static void testme(){
Account a=new Account(Name='aaa',Phone='111');
insert a;
Contact c=new Contact(lastname='aaa',otherphone='222',accountid=a.id);
insert c;
String newPhone='333';
Account rec=[select phone from Account where id=:a.id];
rec.phone=newPhone;
update rec;
Account acc=[select phone from Account where id=:a.id];
System.assertEquals(acc.phone,newPhone);
Contact c1=[select otherphone from Contact where accountid=:a.id];
System.assertEquals(c1.otherphone,rec.phone);
}
}
===================================================
Scenario : 5
Object : Account
Trigger :after update
Logic : When ever account record Active field value is updated as No
then delete the corresponding contacts
Trigger Code:
trigger accountActive on Account (after update) {
List<Id> idList=new List<Id>();
Map<Id,Account> oldMap=Trigger.OldMap;
Map<Id,Account> newMap=Trigger.NewMap;
for(Id aid:oldmap.keySet()){
if(oldMap.get(aid).Active__c=='Yes' && newMap.get(aid).Active__c=='No'){
idList.add(aid);
}
}
List<contact> conList=[select id from Contact where accountid in:idList];
delete conList;
}
Test Class :
@isTest
private class AccountActive {
@isTest
static void testme(){
Account a1=new Account(Name='aaa',Active__c='Yes');
insert a1;
Contact c1=new Contact(lastname='test',accountid=a1.id);
insert c1;
Account acc=[select id,Active__c from Account where id=:a1.id];
acc.Active__c='No';
update acc;
Integer count=[select count() from Contact where accountid=:acc.id];
System.assertEquals(count,0);
/* Changing the value from No to Yes */
Contact c2=new Contact(lastname='test',accountid=a1.id);
insert c2;
Account acc1=[select id,Active__c from Account where id=:a1.id];
acc1.Active__c='Yes';
update acc1;
Integer count1=[select count() from Contact where accountid=:acc1.id];
System.assertNotEquals(count1,0);
}
}
====================================================================
Scenario : 6
Object : Account
Logic : when ever we try to delete a account record which has contacts it
should throw the error
Trigger Code:
trigger accountDelete on Account (before Delete) {
List<Account> accs=[select id,(select id from contacts ) from Account where id in:Trigger.old];
for(Account a:accs){
if(a.contacts.size()>0)
a.addError('Account cannot be deleted where it has contacts');
}
}
======================================================================
Scenario: 7
Object : Account
Logic :
1. When we try to insert a new Account Record
2. Before the record is inserted
3. It should check wheather there are any any account records already
exits in Account object with the same name of new Account
we are inserting
4. if it exits throw error message
Trigger Code: This code is not a good practice as they we have written
soql with in a for loop
trigger dulicateCheck on Account (before insert) {
/* if there are more than 100 records which are inserting this will throw
* Too many soql :101 error on the below code
*/
for(Account a:Trigger.New){
Integer count=[select count() from Account where name=:a.name];
if(count>0){
a.addError('Duplicate Name Exists');
}
}
}
Trigger code with Good practices
/* Already in the Account Object we have the following records
* =============================
* |Name | Industry |
* -------------------------------
* Wipro Banking
* Accenture Technology
* TCS Banking
* DELL Banking
* ==============================
* In that Account object we are trying to insert new Records
* ========================
* Name Industry These two records are in Trigger.New
* =======================
* Wipro Technology
* Accenture Banking
* Capital Education
*/
trigger dulicateCheck on Account (before insert) {
List<String> names=new List<String>();
for(Account a:Trigger.New){
names.add(a.name);
}
/* names will contain {wipro, Accenture,Capital} */
/* SOql query will all the account records whoes names are {Accenture,Wipro,Capital} */
List<Account> dupAccount=[select id,name from Account where name in:names];
/*Above query will fetch the records
* Wipro Banking
* Accenture Technology
* and keep then in dupName
*/
Set<String> dupNames=new Set<String>();
for(Account a:dupAccount){
dupNames.add(a.name);
}
/* dupNames will contain {wipro,Accenture} */
for(Account a1:Trigger.New){
/* if name of the new record is in dupNames then throw error */
if(dupNames.contains(a1.name)){
a1.addError('Duplicate Record already Exists');
}
}
}
Test Code:
@isTest
private class DupNamesTest {
@isTest
static void testme(){
String accname='Testing';
Account a1=new Account(Name='accName');
insert a1;
Integer count=[select count() from Account where Name=:accName];
Account a=new Account();
a.name=accName;
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account where Name=:accName];
if(count>0){
System.assertEquals(count,size);
}else{
System.assertEquals(size,count+1);
}
}
}
================================================
Scenario : 8
Object : Opporutnity
Logic :
1.When ever new opporutunity is created with amount > 50000
or
existing opporutnitis update with amount > 50000
2.then Apex sharing rule and share the record with
User: karthic
Apex Sharing :
1. Every object internally has corresponding sharing object
Ex: opporutity-------OpporutnityShare
Account ---------AccountShare
Customer__c------Customer__Share
Transaction__c---Transaction__Share
2. If we want to create Apex sharing rules OWD on the object
should be private |Public Read
3. We can grant access of Read| Write
4. ApexSharing rule with OpporutnityShare we have to provide
the following data
1.OpportunityId : This is the id of the opporutnity record
which we to share
2.OpportunityAccessLevel : Type of the access we want to grant
on the record
values : Read |Edit| All
3.RowCause :This will specify reason for sharing
values : Manual |Rule |Sales Team |Owner
4. UserOrGroupId : This is the id of the user or group with
whom we want to share
Trigger code :
trigger shareRecord on Opportunity (after insert,after update) {
List<OpportunityShare> share=new List<OpportunityShare>();
User u=[select id from User where alias='kshar'];
for(Opportunity op:Trigger.New){
if(op.amount>50000){
OpportunityShare p=new OpportunityShare();
p.OpportunityId=op.id;
p.UserOrGroupId=u.id;
p.OpportunityAccessLevel='Read';
p.RowCause='Manual';
share.add(p);
}
}
insert share;
}
===================================================
Scenario : 9
Object : Application__c
Logic : When ever new application
Before Insert
1. Check the pancard no of the application record is in the
black list object
2.If pancard is in the black lsit set the status as rejected
otherwise set status as pending
2. If the record status is updated as Approved then create
new customer record with same details of the application
Step 1: Create Application Object with follwing fields
Field : LastName : Text
: FirstName: Text
: PanCard : Text
: Status : PickList(Pending,Rejeced,Approved)
Step 2: Create Customer Object with following fields
Field : LastName : Text
: FirstName: Text
: PanCard : Text
Step 3: Create BlakcList Object with the following fields
Field : Pancard :Text
Trigger handler class :
public class ApplicationHandler {
public Static void afterUpdate(Map<Id,Applicaiton__c> old ,List<Application__c> appList){
List<Customer__c> custList=new List<Customer__c>();
for(Application__c a:appList){
if(old.get(a.id).Status__c!='Approved' && a.status__c=='Approved' ){
Customer__c c=new Customer__c();
c.lastName__c=a.lastName__c;
c.FirstName__c=a.FirstName__c;
c.pancard__c=a.pancard__c;
custList.add(c);
}
}
insert custList;
}
public static void beforeInsert(List<Application__c> appList){
List<String> pancards=new List<String>();
for(Application__c a:appList){
pancards.add(a.pancard__C);
}
List<BlackList__c> blist=[select pancard__C from BlackList__c where Pancard__c in: pancards];
Set<String> duplicates=new Set<String>();
for(BlacklIst__c b:blist){
duplicates.add(b.pancard__C);
}
for(Application__c ap:appList){
if(duplicates.contains(ap.pancard__c)){
ap.status__C='Rejected';
}else{
ap.Status__c='Pending';
}
}
}
}
Trigger :
trigger appTrigger on Application__c (before insert,after update) {
if(Trigger.isBefore && Trigger.isInsert){
ApplicationHandler.beforeInsert(Trigger.new);
}
if(Trigger.after && Trigger.update){
ApplicationHandler.afterUpdate(Trigger.oldMap,Trigger.new);
}
}
=================================================================
Scenario :10
Recursive Trigger:
If a trigger calls itself we call it as recursive Triggers.
Ex: if we have written a insert trigger on a object and with in
the trigger if we are trying perfom insert operation on the
same object then it will throw recursive trigger
Example :
trigger contactRecords on Contact (before insert) {
Contact c1=new Contact(lastname='Testing');
insert c1;
}
Above trigger will throw recursive trigger exception .
Recursive triggers are handled using static boolean flag varibles
Quick Example :
public class Contacthandler {
public Static boolean flag =true;
public static void beforeInsert(){
if(flag==true){
flag=false;
Contact c1=new Contact(lastname='Recursive');
insert c1;
}
}
}
Trigger:
trigger contactRecords on Contact (before insert) {
Contacthandler.beforeInsert();
}
=======================================
1.
UPDATE
======================================================================
befor Update Triggers
=======================================================================
1.On the records which are Trigger.New in before Update
Trigger.New
------------------------------
Read Write SOQL DML
-------------------------------
Yes Yes No No
2.On the records which are Trigger.NewMap in before Update
Trigger.NewMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes Yes No No
3.On the records which are Trigger.old in before Update
Trigger.old
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes No
4. On the records which are Trigger.oldMap in before Update
Trigger.oldMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes No
===============================================================
after Update Trigger
================================================================
1.On the records which are Trigger.New in after Update
Trigger.New
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes Yes
2. On the records which are Trigger.NewMap in after Update
Trigger.NewMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes Yes
3.On the records which are Trigger.old in after Update
Trigger.old
------------------------------
Read Write SOQL DML
-------------------------------
Yes No No No
4. On the records which are Trigger.oldMap in after Update
Trigger.oldMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes No No No
Basic Scenario:
1. Object : Account
Fields : Phone
2. Object : Contact
Field : Account(Lookup)
MobilePhone
Scenario 6: When ever the Account' object phone no is modified ,Its corresponding child
contacts records mobilePhone values should be replaced with
Account's New phoneNo
Trigger :
----------
trigger Scenario6 on Account (before update) {
List<Account> oldList=[select id,phone,(select mobilephone from Contacts) from Account where id In: Trigger.Old];
List<Contact> cons=new List<Contact>();
for(Account a:oldList){
for(Contact c:a.contacts){
c.MobilePhone=Trigger.newMap.get(a.id).Phone;
cons.add(c);
}
}
update cons;
}
TestClass :
-----------
@isTest
private class scenario6 {
@isTest
static void testme(){
Account a=new Account(Name='aaa',phone='111');
insert a;
Contact c1=new Contact(lastname='test',mobilePhone='111',accountid=a.id);
insert c1;
a.phone='123';
try{
update a;
}catch(Exception e){
System.debug(e);
}
Account acc=[select id ,phone from Account where id=:a.id];
Contact con=[select id,mobilePhone from Contact where Id=:c1.id];
System.assertEquals(acc.phone,'123');
System.assertEquals(con.MobilePhone,'123');
}
}
Scenario 7:
Object : Account
Fields :Manager : Text (Create this custom Field first)
: Industry : PickList( Standard Field)
Object : User
Fields : Account_Manager : Text Fields
Task : When ever the industry field value is modified as banking then
1.Fetch the user who is the owner of the Account Record
2.Update the Account_Manager field on the user with Manager field value
Trigger:
trigger Scenario7 on Account (before update ) {
Map<Id,Account> oldMap=Trigger.oldMap;
Map<Id,Account> newMap=Trigger.newMap;
List<Id> accs=new List<Id>();
for(Id aid:oldMap.keySet()){
if(oldMap.get(aid).Industry !=newMap.get(aid).Industry && newMap.get(aid).Industry=='Banking'){
accs.add(aid);
}
}
List<Id> userids=new List<Id>();
for(Id mid:accs){
userids.add(newMap.get(mid).ownerid);
}
List<user> newUsers=new List<User>();
Map<Id,User> userMap=new Map<Id,User>([select id,Account_Manager__c from User where id in :userids]);
for(Id mid:accs){
Id uid=newMap.get(mid).ownerid;
User u=userMap.get(uid);
u.Account_Manager__c=newMap.get(mid).Manager__c;
newusers.add(u);
}
update newusers;
}
Scenario 8:
Object : Account
Field : Name
Object : Contact
1.Before insert
1.When we are inserting new account record first check if there are
any duplicate records with same name already existing
2. if they are existing throw error message
2.after update :
1. Check wheather there are any contact records already existing
for the give account
2. if no contacts are existing create new contact
Trigger Class :
public class TriggerExample {
public static void beforeInsert(List<Account> accs){
List<String> names=new List<String>();
for(Account a:accs){
names.add(a.name);
}
List<Account> duplicates=[select id,name from Account where name in:names];
if(duplicates.size()>0){
Set<String> dupnames=new Set<String>();
for(Account a:duplicates){
dupNames.add(a.name);
}
for(Account ac:accs){
if(dupNames.contains(ac.Name))
ac.addError('Duplicate name Exists');
}
}
}
public static void afterUpdate(List<Account> accs){
List<Contact> cons=new List<Contact>();
List<Account> accounts=[select id,name,phone,(select id from Contacts) from Account where id in:accs];
for(Account a:accounts){
if(a.contacts.size()==0){
Contact c=new Contact();
c.accountid=a.id;
c.lastname=a.name;
c.phone=a.phone;
cons.add(c);
}
}
insert cons;
}
}
Trigger:
---------
trigger scenario8 on Account (before insert,after update) {
if(Trigger.isBefore && Trigger.isInsert){
TriggerExample.beforeInsert(Trigger.New);
}
if(Trigger.isAfter && Trigger.isUpdate){
TriggerExample.afterUpdate(Trigger.New);
}
}
Test Class :
@isTest
private class Scenario8 {
@isTest
static void testme(){
Account a1=new Account(Name='aaa');
insert a1;
Integer count=[select count() from Account];
Integer size=[select count() from Contact];
Account a2=new Account(Name='aaa');
try{
insert a2;
}Catch(Exception e){
System.debug(e);
}
Integer newCount=[select count() from Account];
System.assertEquals(count,newCount);
a1.phone='123';
update a1;
Account acc=[select id,phone from Account where phone='123'];
System.assertEquals(acc.phone,'123');
Integer newSize=[select count() from Contact];
System.assertEquals(size+1,newSize);
}
}
==================
Q::Which Trigger Context variables are allowed in before insert.
Ans :
-------------------------------------------------------------------------------
Trigger.New Trigger.NewMap Trigger.old Trigger.oldMap
--------------------------------------------------------------------------------
before insert Yes No No No
Q:: Which Operations are allowed on Trigger.New in before insert trigger
Ans:
Trigger.New
----------------------------
Read Write SOQL DML
----------------------------
Yes Yes No No
Scenario
==>>Basic Level Trigger scenario's on before insert
Scenario 1: When ever we are trying to insert new Account record with industry
as banking then Annualrevenue should be set as 50000;
Code :
trigger scenario1 on Account (before insert) {
for(Account a:Trigger.New){
if(a.industry=='Banking'){
a.annualRevenue=50000;
}
}
}
Test Class :
@isTest
private class Scenario1Test {
@isTest
static void test(){
Integer count=[select count() from Account];
Account a1=new Account(Name='aaa',Industry='Banking');
try{
insert a1;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
System.assertEquals(count+1,size);
Account acc=[select id, AnnualRevenue from Account where id=:a1.id];
System.assertEquals(acc.annualRevenue,50000);
}
}
Scneario 2: When ever new Account is creatd with out phone no it should throw
error message
Trigger :
trigger scenario2 on Account (before insert) {
for(Account a:Trigger.New){
if(a.phone=='' || a.phone==null){
a.addError('Phone no is a must ');
}
}
}
Test Class :
@isTest
private class scenario2 {
@isTest
static void testme(){
Integer count=[select count() from Account];
Account a=new Account(Name='aaa');
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
System.assertEquals(count,size);
}
}
Scneario 3:When ever new Application is created with Application Type as New
1. If pancard no is already existing in the black list then
set application status as rejected
2.If the pancard no is not available in black list set the application
status as pending
Solution:
Object :Application
Fields : Type : PicKList (New ,cancel,Block)
Status : PickList( Approved,Rejected,Pending)
Pancard: Text
Object: BlackList
Fields : Name : Text
Trigger Code:
trigger scenario3 on Application__c (before insert) {
List<String> pancards=new List<String>();
for(Application__c ap:Trigger.New){
if(ap.Type__c=='New')
pancards.add(ap.Pancard__c);
}
List<BlackList__c> black=[select id,Name from BlackList__c where name in :pancards];
Set<String> panList=new Set<string>();
if(black.size()!=0){
for(BlackList__c b:black){
panList.add(b.name);
}
}
for(Application__c a:Trigger.New){
if(panlist.contains(a.pancard__c)){
a.status__c='Rejected';
}else{
a.status__c='Pending';
}
}
}
Test Class :
@isTest
private class Scenario3 {
testmethod static void testme(){
BlackList__c b1=new BlackList__c();
b1.Name='1234';
insert b1;
Application__c ap1=new Application__c();
ap1.Applicant_Name__c='aaa';
ap1.Type__c='New';
ap1.Pancard__c='1234';
insert ap1;
Application__c res1=[select id,status__c from Application__c where id=:ap1.id];
System.assertEquals(res1.Status__c,'Rejected');
Application__c ap2=new Application__c();
ap2.Applicant_Name__c='aaa';
ap2.Type__c='Block';
ap2.Pancard__c='4567';
insert ap2;
Application__c res2=[select id,status__c from Application__c where id=:ap2.id];
System.assertEquals(res2.Status__c,'Pending');
Application__c ap3=new Application__c();
ap3.Applicant_Name__c='aaa';
ap3.Type__c='New';
ap3.Pancard__c='3456';
insert ap3;
Application__c res3=[select id,status__c from Application__c where id=:ap3.id];
System.assertEquals(res3.Status__c,'Pending');
}
}
Scenario 4: When ever new Account is created successfully corresponding contact
should be created using the details from Account
Trigger :
trigger scenario4 on Account (after insert) {
List<Contact> cons=new List<Contact>();
for(Account a:Trigger.New){
Contact c=new Contact();
c.lastname=a.name;
c.phone=a.phone;
c.accountid=a.id;
cons.add(c);
}
insert cons;
}
TestClass :
@isTest
private class scenario4Test {
@isTest(seealldata=true)
static void testme(){
Integer accCount=[select count() from Account];
Integer conCount=[select count() from Contact];
Account a=new Account(Name='aaa',Phone='123');
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer count=[select count() from Account];
Integer size=[select count() from Contact];
System.assertEquals(acccount+1,count);
System.assertEquals(conCount+1,size);
Contact con=[select accountid from Contact where accountid=:a.id];
System.assertEquals(con.lastname,a.name);
System.assertEquals(con.phone,a.phone);
System.assertEquals(con.accountid,a.id);
}
}
Scenario 5: When ever a new Opportunity is created .Then share that record with
user
Note : before you write the trigger
OWD: opporutnity :Private
Trigger:
trigger scenario5 on Opportunity (after insert) {
User u=[select id from User where alias='kshar'];
List<OpportunityShare> records=new List<opportunityShare>();
for(Opportunity op:Trigger.New){
OpportunityShare share=new OpportunityShare();
share.OpportunityId=op.id;
share.rowCause='Manual';
share.OpportunityAccessLevel='Edit';
share.UserOrGroupId=u.id;
records.add(share);
}
insert records;
}
____________________
__________________
trigger example on Application__c (before insert,after insert) {
if(Trigger.isInsert && Trigger.isBefore){
for(Application__c a:Trigger.New){
if(a.ID_Proof__c!='Pancard'){
a.Address_Proof__c=a.ID_Proof__c;
}
}
}
if(Trigger.isAfter && Trigger.isInsert){
List<Application__c> newList=[select CreditLimit__c,Salary__C from Application__c where id in:Trigger.New];
for(Application__c ap:newList){
if(ap.salary__c>50000){
ap.CreditLImit__c=3*ap.salary__C;
}else{
ap.CreditLImit__c=2*ap.salary__c;
}
}
update newList;
}
}
===========================================
Scenario 1: When ever a new Account record is inserted if the industry is
'Banking' set the annualrevenue as 50,00,000 before insert
Code :
trigger annualexample on Account (before insert) {
List<Account> accs=Trigger.New;
for(Account a:accs){
if(a.industry=='Banking')
a.annualRevenue=5000000;
}
}
Test Class :
@isTest
public class AnnualTest {
@isTest
static void testme(){
Integer count=[select count() from Account];
Account a1=new Account(Name='aaa',Industry='Banking');
Account a2=new Account(name='bbb',Industry='Energy');
try{
insert a1;
insert a2;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
System.assertEquals(size,count+2);
Account acc=[select annualrevenue from Account where id=:a1.id];
System.assertEquals(acc.annualRevenue,5000000);
Account acc1=[select annualrevenue from Account where id=:a2.id];
System.assertNotEquals(acc1.annualRevenue,a1.AnnualRevenue);
}
}
=====================================================================
Scenario 2:
Object : Account
Validation Rule : if the annualrevenue < 10,000 then throw error
Trigger :Create a before insert tigger on Account w which will modify the
annualrevenu of new records which we are inserting as 5,00,000
Code: trigger annualvalidation on Account (before insert) {
for(Account a:Trigger.New){
a.annualRevenue=500000;
}
}
Test Class :
@isTest
private class AnnualValidation {
@isTest
static void testme(){
Integer count=[select count() from Account];
Account a=new Account(Name='bbb',AnnualRevenue=900);
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account];
Account acc=[select annualRevenue from Account where id=:a.id];
System.assertEquals(size,count+1);
System.assertEquals(acc.annualRevenue,500000);
}
}
======================================================================
Scenario 3:
Object : Account
Trigger: After Insert
Description : When ever new Account record is successfully created then
create the corresponding contact record for the account
with
account name as contact lastname
account phone as contact phone
Trigger Code:
trigger accountAfter on Account (after insert) {
List<Contact> cons=new List<Contact>();
for(Account a: Trigger.New){
Contact c=new Contact();
c.accountid=a.id;
c.lastname=a.name;
c.phone=a.phone;
cons.add(c);
}
insert cons;
}
Test Class :
@isTest
private class AccountAfter {
@isTest
static void testme(){
Integer count=[select count() from Account];
Integer size=[select count() from Contact];
Account a=new Account(Name='Testing',phone='111');
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer newCount=[select count() from Account];
Integer newsize=[select count() from Contact];
Contact c=[select lastname,phone from Contact where accountid=:a.id];
System.assertEquals(c.lastname,a.name);
System.assertEquals(c.phone,a.phone);
}
}
Create a New Account Record and test it
====================================================================
Scenario :4
Object : Account
Trigger : before Update
When ever the phone no in the account record is modified
then fetch all the contacts of the account record and update the
contact otherphone no field value with account phone no field value;
Trigger Code:
trigger accountphone on Account (before update) {
List<ID> accs=new List<ID>();
Map<Id,Account> oldMap=Trigger.oldMap;
Map<Id,Account> newMap=Trigger.NewMap;
for(Id aid:oldMap.keySet()){
if(oldMap.get(aid).phone!=newMap.get(aid).phone)
accs.add(aid);
}
List<Contact> conList=[select otherphone,accountid from contact where accountid in:accs];
if(conList.size()>0){
for(contact c:conList){
c.otherphone=newMap.get(c.accountid).phone;
}
update conList;
}
}
Test Class :
@isTest
public class accountphone {
@isTest
static void testme(){
Account a=new Account(Name='aaa',Phone='111');
insert a;
Contact c=new Contact(lastname='aaa',otherphone='222',accountid=a.id);
insert c;
String newPhone='333';
Account rec=[select phone from Account where id=:a.id];
rec.phone=newPhone;
update rec;
Account acc=[select phone from Account where id=:a.id];
System.assertEquals(acc.phone,newPhone);
Contact c1=[select otherphone from Contact where accountid=:a.id];
System.assertEquals(c1.otherphone,rec.phone);
}
}
===================================================
Scenario : 5
Object : Account
Trigger :after update
Logic : When ever account record Active field value is updated as No
then delete the corresponding contacts
Trigger Code:
trigger accountActive on Account (after update) {
List<Id> idList=new List<Id>();
Map<Id,Account> oldMap=Trigger.OldMap;
Map<Id,Account> newMap=Trigger.NewMap;
for(Id aid:oldmap.keySet()){
if(oldMap.get(aid).Active__c=='Yes' && newMap.get(aid).Active__c=='No'){
idList.add(aid);
}
}
List<contact> conList=[select id from Contact where accountid in:idList];
delete conList;
}
Test Class :
@isTest
private class AccountActive {
@isTest
static void testme(){
Account a1=new Account(Name='aaa',Active__c='Yes');
insert a1;
Contact c1=new Contact(lastname='test',accountid=a1.id);
insert c1;
Account acc=[select id,Active__c from Account where id=:a1.id];
acc.Active__c='No';
update acc;
Integer count=[select count() from Contact where accountid=:acc.id];
System.assertEquals(count,0);
/* Changing the value from No to Yes */
Contact c2=new Contact(lastname='test',accountid=a1.id);
insert c2;
Account acc1=[select id,Active__c from Account where id=:a1.id];
acc1.Active__c='Yes';
update acc1;
Integer count1=[select count() from Contact where accountid=:acc1.id];
System.assertNotEquals(count1,0);
}
}
====================================================================
Scenario : 6
Object : Account
Logic : when ever we try to delete a account record which has contacts it
should throw the error
Trigger Code:
trigger accountDelete on Account (before Delete) {
List<Account> accs=[select id,(select id from contacts ) from Account where id in:Trigger.old];
for(Account a:accs){
if(a.contacts.size()>0)
a.addError('Account cannot be deleted where it has contacts');
}
}
======================================================================
Scenario: 7
Object : Account
Logic :
1. When we try to insert a new Account Record
2. Before the record is inserted
3. It should check wheather there are any any account records already
exits in Account object with the same name of new Account
we are inserting
4. if it exits throw error message
Trigger Code: This code is not a good practice as they we have written
soql with in a for loop
trigger dulicateCheck on Account (before insert) {
/* if there are more than 100 records which are inserting this will throw
* Too many soql :101 error on the below code
*/
for(Account a:Trigger.New){
Integer count=[select count() from Account where name=:a.name];
if(count>0){
a.addError('Duplicate Name Exists');
}
}
}
Trigger code with Good practices
/* Already in the Account Object we have the following records
* =============================
* |Name | Industry |
* -------------------------------
* Wipro Banking
* Accenture Technology
* TCS Banking
* DELL Banking
* ==============================
* In that Account object we are trying to insert new Records
* ========================
* Name Industry These two records are in Trigger.New
* =======================
* Wipro Technology
* Accenture Banking
* Capital Education
*/
trigger dulicateCheck on Account (before insert) {
List<String> names=new List<String>();
for(Account a:Trigger.New){
names.add(a.name);
}
/* names will contain {wipro, Accenture,Capital} */
/* SOql query will all the account records whoes names are {Accenture,Wipro,Capital} */
List<Account> dupAccount=[select id,name from Account where name in:names];
/*Above query will fetch the records
* Wipro Banking
* Accenture Technology
* and keep then in dupName
*/
Set<String> dupNames=new Set<String>();
for(Account a:dupAccount){
dupNames.add(a.name);
}
/* dupNames will contain {wipro,Accenture} */
for(Account a1:Trigger.New){
/* if name of the new record is in dupNames then throw error */
if(dupNames.contains(a1.name)){
a1.addError('Duplicate Record already Exists');
}
}
}
Test Code:
@isTest
private class DupNamesTest {
@isTest
static void testme(){
String accname='Testing';
Account a1=new Account(Name='accName');
insert a1;
Integer count=[select count() from Account where Name=:accName];
Account a=new Account();
a.name=accName;
try{
insert a;
}catch(Exception e){
System.debug(e);
}
Integer size=[select count() from Account where Name=:accName];
if(count>0){
System.assertEquals(count,size);
}else{
System.assertEquals(size,count+1);
}
}
}
================================================
Scenario : 8
Object : Opporutnity
Logic :
1.When ever new opporutunity is created with amount > 50000
or
existing opporutnitis update with amount > 50000
2.then Apex sharing rule and share the record with
User: karthic
Apex Sharing :
1. Every object internally has corresponding sharing object
Ex: opporutity-------OpporutnityShare
Account ---------AccountShare
Customer__c------Customer__Share
Transaction__c---Transaction__Share
2. If we want to create Apex sharing rules OWD on the object
should be private |Public Read
3. We can grant access of Read| Write
4. ApexSharing rule with OpporutnityShare we have to provide
the following data
1.OpportunityId : This is the id of the opporutnity record
which we to share
2.OpportunityAccessLevel : Type of the access we want to grant
on the record
values : Read |Edit| All
3.RowCause :This will specify reason for sharing
values : Manual |Rule |Sales Team |Owner
4. UserOrGroupId : This is the id of the user or group with
whom we want to share
Trigger code :
trigger shareRecord on Opportunity (after insert,after update) {
List<OpportunityShare> share=new List<OpportunityShare>();
User u=[select id from User where alias='kshar'];
for(Opportunity op:Trigger.New){
if(op.amount>50000){
OpportunityShare p=new OpportunityShare();
p.OpportunityId=op.id;
p.UserOrGroupId=u.id;
p.OpportunityAccessLevel='Read';
p.RowCause='Manual';
share.add(p);
}
}
insert share;
}
===================================================
Scenario : 9
Object : Application__c
Logic : When ever new application
Before Insert
1. Check the pancard no of the application record is in the
black list object
2.If pancard is in the black lsit set the status as rejected
otherwise set status as pending
2. If the record status is updated as Approved then create
new customer record with same details of the application
Step 1: Create Application Object with follwing fields
Field : LastName : Text
: FirstName: Text
: PanCard : Text
: Status : PickList(Pending,Rejeced,Approved)
Step 2: Create Customer Object with following fields
Field : LastName : Text
: FirstName: Text
: PanCard : Text
Step 3: Create BlakcList Object with the following fields
Field : Pancard :Text
Trigger handler class :
public class ApplicationHandler {
public Static void afterUpdate(Map<Id,Applicaiton__c> old ,List<Application__c> appList){
List<Customer__c> custList=new List<Customer__c>();
for(Application__c a:appList){
if(old.get(a.id).Status__c!='Approved' && a.status__c=='Approved' ){
Customer__c c=new Customer__c();
c.lastName__c=a.lastName__c;
c.FirstName__c=a.FirstName__c;
c.pancard__c=a.pancard__c;
custList.add(c);
}
}
insert custList;
}
public static void beforeInsert(List<Application__c> appList){
List<String> pancards=new List<String>();
for(Application__c a:appList){
pancards.add(a.pancard__C);
}
List<BlackList__c> blist=[select pancard__C from BlackList__c where Pancard__c in: pancards];
Set<String> duplicates=new Set<String>();
for(BlacklIst__c b:blist){
duplicates.add(b.pancard__C);
}
for(Application__c ap:appList){
if(duplicates.contains(ap.pancard__c)){
ap.status__C='Rejected';
}else{
ap.Status__c='Pending';
}
}
}
}
Trigger :
trigger appTrigger on Application__c (before insert,after update) {
if(Trigger.isBefore && Trigger.isInsert){
ApplicationHandler.beforeInsert(Trigger.new);
}
if(Trigger.after && Trigger.update){
ApplicationHandler.afterUpdate(Trigger.oldMap,Trigger.new);
}
}
=================================================================
Scenario :10
Recursive Trigger:
If a trigger calls itself we call it as recursive Triggers.
Ex: if we have written a insert trigger on a object and with in
the trigger if we are trying perfom insert operation on the
same object then it will throw recursive trigger
Example :
trigger contactRecords on Contact (before insert) {
Contact c1=new Contact(lastname='Testing');
insert c1;
}
Above trigger will throw recursive trigger exception .
Recursive triggers are handled using static boolean flag varibles
Quick Example :
public class Contacthandler {
public Static boolean flag =true;
public static void beforeInsert(){
if(flag==true){
flag=false;
Contact c1=new Contact(lastname='Recursive');
insert c1;
}
}
}
Trigger:
trigger contactRecords on Contact (before insert) {
Contacthandler.beforeInsert();
}
=======================================
1.
UPDATE
======================================================================
befor Update Triggers
=======================================================================
1.On the records which are Trigger.New in before Update
Trigger.New
------------------------------
Read Write SOQL DML
-------------------------------
Yes Yes No No
2.On the records which are Trigger.NewMap in before Update
Trigger.NewMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes Yes No No
3.On the records which are Trigger.old in before Update
Trigger.old
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes No
4. On the records which are Trigger.oldMap in before Update
Trigger.oldMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes No
===============================================================
after Update Trigger
================================================================
1.On the records which are Trigger.New in after Update
Trigger.New
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes Yes
2. On the records which are Trigger.NewMap in after Update
Trigger.NewMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes No Yes Yes
3.On the records which are Trigger.old in after Update
Trigger.old
------------------------------
Read Write SOQL DML
-------------------------------
Yes No No No
4. On the records which are Trigger.oldMap in after Update
Trigger.oldMap
------------------------------
Read Write SOQL DML
-------------------------------
Yes No No No
Basic Scenario:
1. Object : Account
Fields : Phone
2. Object : Contact
Field : Account(Lookup)
MobilePhone
Scenario 6: When ever the Account' object phone no is modified ,Its corresponding child
contacts records mobilePhone values should be replaced with
Account's New phoneNo
Trigger :
----------
trigger Scenario6 on Account (before update) {
List<Account> oldList=[select id,phone,(select mobilephone from Contacts) from Account where id In: Trigger.Old];
List<Contact> cons=new List<Contact>();
for(Account a:oldList){
for(Contact c:a.contacts){
c.MobilePhone=Trigger.newMap.get(a.id).Phone;
cons.add(c);
}
}
update cons;
}
TestClass :
-----------
@isTest
private class scenario6 {
@isTest
static void testme(){
Account a=new Account(Name='aaa',phone='111');
insert a;
Contact c1=new Contact(lastname='test',mobilePhone='111',accountid=a.id);
insert c1;
a.phone='123';
try{
update a;
}catch(Exception e){
System.debug(e);
}
Account acc=[select id ,phone from Account where id=:a.id];
Contact con=[select id,mobilePhone from Contact where Id=:c1.id];
System.assertEquals(acc.phone,'123');
System.assertEquals(con.MobilePhone,'123');
}
}
Scenario 7:
Object : Account
Fields :Manager : Text (Create this custom Field first)
: Industry : PickList( Standard Field)
Object : User
Fields : Account_Manager : Text Fields
Task : When ever the industry field value is modified as banking then
1.Fetch the user who is the owner of the Account Record
2.Update the Account_Manager field on the user with Manager field value
Trigger:
trigger Scenario7 on Account (before update ) {
Map<Id,Account> oldMap=Trigger.oldMap;
Map<Id,Account> newMap=Trigger.newMap;
List<Id> accs=new List<Id>();
for(Id aid:oldMap.keySet()){
if(oldMap.get(aid).Industry !=newMap.get(aid).Industry && newMap.get(aid).Industry=='Banking'){
accs.add(aid);
}
}
List<Id> userids=new List<Id>();
for(Id mid:accs){
userids.add(newMap.get(mid).ownerid);
}
List<user> newUsers=new List<User>();
Map<Id,User> userMap=new Map<Id,User>([select id,Account_Manager__c from User where id in :userids]);
for(Id mid:accs){
Id uid=newMap.get(mid).ownerid;
User u=userMap.get(uid);
u.Account_Manager__c=newMap.get(mid).Manager__c;
newusers.add(u);
}
update newusers;
}
Scenario 8:
Object : Account
Field : Name
Object : Contact
1.Before insert
1.When we are inserting new account record first check if there are
any duplicate records with same name already existing
2. if they are existing throw error message
2.after update :
1. Check wheather there are any contact records already existing
for the give account
2. if no contacts are existing create new contact
Trigger Class :
public class TriggerExample {
public static void beforeInsert(List<Account> accs){
List<String> names=new List<String>();
for(Account a:accs){
names.add(a.name);
}
List<Account> duplicates=[select id,name from Account where name in:names];
if(duplicates.size()>0){
Set<String> dupnames=new Set<String>();
for(Account a:duplicates){
dupNames.add(a.name);
}
for(Account ac:accs){
if(dupNames.contains(ac.Name))
ac.addError('Duplicate name Exists');
}
}
}
public static void afterUpdate(List<Account> accs){
List<Contact> cons=new List<Contact>();
List<Account> accounts=[select id,name,phone,(select id from Contacts) from Account where id in:accs];
for(Account a:accounts){
if(a.contacts.size()==0){
Contact c=new Contact();
c.accountid=a.id;
c.lastname=a.name;
c.phone=a.phone;
cons.add(c);
}
}
insert cons;
}
}
Trigger:
---------
trigger scenario8 on Account (before insert,after update) {
if(Trigger.isBefore && Trigger.isInsert){
TriggerExample.beforeInsert(Trigger.New);
}
if(Trigger.isAfter && Trigger.isUpdate){
TriggerExample.afterUpdate(Trigger.New);
}
}
Test Class :
@isTest
private class Scenario8 {
@isTest
static void testme(){
Account a1=new Account(Name='aaa');
insert a1;
Integer count=[select count() from Account];
Integer size=[select count() from Contact];
Account a2=new Account(Name='aaa');
try{
insert a2;
}Catch(Exception e){
System.debug(e);
}
Integer newCount=[select count() from Account];
System.assertEquals(count,newCount);
a1.phone='123';
update a1;
Account acc=[select id,phone from Account where phone='123'];
System.assertEquals(acc.phone,'123');
Integer newSize=[select count() from Contact];
System.assertEquals(size+1,newSize);
}
}