function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
srikanth11srikanth11 

bulkify trigger

can any one tell me how can i bulkify this trigger

trigger pointamount on Opportunity ( after insert,after update,before delete)
 {
 if(trigger.isInsert)
  {
 for (Opportunity  o : Trigger.new)
    {
    if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
    {
points__c  a = new Points__c();
a.Account__c = o.Accountid;          
a.Points_Transaction_Amount__c =o.amount-o.amount*2;
a.Points_Transaction_Reason__c =' Points Redeemed';  
a.Points_Transaction_Date__c=o.CloseDate;
a.Purchaser_Email__c=o.Contact_Email__c;
a.Opportunity__c=o.id;
a.Purchaser_Name__c=o.Purchaser_Name__c;
insert a;         


 }
 
 }
 }
 
 
 
 
  if(trigger.isupdate)
   {
  for (Opportunity  o : Trigger.new)
    {
    if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
   {
  

     Points__c[] fn =[select id,account__c,opportunity__c from Points__c where opportunity__c=:o.id];
    // fn[0].Points_Transaction_Amount__c=o.amount-o.amount*2;
    // update fn;   
         
 if(fn.size()==0){
 points__c  a = new Points__c();
a.Account__c = o.Accountid;          
a.Points_Transaction_Amount__c =o.amount-o.amount*2;
a.Points_Transaction_Reason__c =' Points Redeemed';  
a.Points_Transaction_Date__c=o.CloseDate;
a.Purchaser_Email__c=o.Contact_Email__c;
a.Opportunity__c=o.id;
a.Purchaser_Name__c=o.Purchaser_Name__c;
insert a;  
}
if(fn.size()>0){  
fn[0].Points_Transaction_Amount__c=o.amount-o.amount*2;
update fn;   
}
 
 
}



}



}
if(trigger.isdelete  )
{
for (Opportunity  o : Trigger.old)
    {
  if(o.accountid!=null &&o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
    {
  

Points__c fn =[select id,account__c,opportunity__c from Points__c where opportunity__c=:o.id  ];

delete fn;
}
}

}




}

 

Chamil MadusankaChamil Madusanka

Hi,

 

Try this.

 

trigger pointamount on Opportunity ( after insert,after update,before delete)
 {
 Set<Id> OId = new Set<Id>();
  
		for (Opportunity  o : Trigger.new)
		{
			OId.add(o.Id);
		}
	List<Points__c> fn =[select id,account__c,opportunity__c from Points__c where opportunity__c in: OId];	
 
	if(trigger.isInsert)
	{
		for (Opportunity  o : Trigger.new)
		{
			if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
			{
				points__c  a = new Points__c();
				a.Account__c = o.Accountid;          
				a.Points_Transaction_Amount__c =o.amount-o.amount*2;
				a.Points_Transaction_Reason__c =' Points Redeemed';  
				a.Points_Transaction_Date__c=o.CloseDate;
				a.Purchaser_Email__c=o.Contact_Email__c;
				a.Opportunity__c=o.id;
				a.Purchaser_Name__c=o.Purchaser_Name__c;
				insert a;         


			}
 
		}
	}
 
 
  if(trigger.isupdate)
  {
  
		
		for (Opportunity  o : Trigger.new)
		{
			for(Points__c pnts : fn)
			{
				if(o.Id == pnts.opportunity__c)
				{
			
						if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
						{
							
				// fn[0].Points_Transaction_Amount__c=o.amount-o.amount*2;
				// update fn;   
					 
							if(fn.size()==0)
							{
								points__c  a = new Points__c();
								a.Account__c = o.Accountid;          
								a.Points_Transaction_Amount__c =o.amount-o.amount*2;
								a.Points_Transaction_Reason__c =' Points Redeemed';  
								a.Points_Transaction_Date__c=o.CloseDate;
								a.Purchaser_Email__c=o.Contact_Email__c;
								a.Opportunity__c=o.id;
								a.Purchaser_Name__c=o.Purchaser_Name__c;
								insert a;  
							}
							
							if(fn.size()>0)
							{  
								pnts.Points_Transaction_Amount__c=o.amount-o.amount*2;
								update pnts;   
							}	
			 
			 
						}
				}	
			}
		}
	}
	
	if(trigger.isdelete  )
	{
		for (Opportunity  o : Trigger.old)
		{
			for(Points__c pnts : fn)
			{
			if(o.Id == pnts.opportunity__c)
			{
			if(o.accountid!=null &&o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
			{
  
				
				delete pnts;
			}
			}
			}
		}

	}




}

For further details : http://wiki.developerforce.com/index.php/Best_Practice:_Bulkify_Your_Code

 

 If a reply to a post answers your question or resolves your problem, please mark it as the solution to the post so that others may benefit.

 

Chamil's Blog

ritika@developerforceritika@developerforce

Hi,

 

Ideally you should nto be using dml statements inside a for loop. In a bulk trigger, this alone may cause your code to cross governor limits.

For e.g. -

 

Instead of this part -

for (Opportunity  o : Trigger.new)
		{
			if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter')
			{
				points__c  a = new Points__c();
				a.Account__c = o.Accountid;          
				a.Points_Transaction_Amount__c =o.amount-o.amount*2;
				a.Points_Transaction_Reason__c =' Points Redeemed';  
				a.Points_Transaction_Date__c=o.CloseDate;
				a.Purchaser_Email__c=o.Contact_Email__c;
				a.Opportunity__c=o.id;
				a.Purchaser_Name__c=o.Purchaser_Name__c;
				insert a;         


			}
 
		}

Write it like this

 

List<points__c> pointsToInsert = new list<points__c>();
for (Opportunity o : Trigger.new) { if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter') { points__c a = new Points__c(); a.Account__c = o.Accountid; a.Points_Transaction_Amount__c =o.amount-o.amount*2; a.Points_Transaction_Reason__c =' Points Redeemed'; a.Points_Transaction_Date__c=o.CloseDate; a.Purchaser_Email__c=o.Contact_Email__c; a.Opportunity__c=o.id; a.Purchaser_Name__c=o.Purchaser_Name__c; pointsToInsert.add(a); } }
insert pointsToInsert



This will ensure lesser DML statements run, when running in bulk.

Hope this helps.

 

Regards,

Ritika

srikanth11srikanth11

hi brother very much thanks for u r reply and u r trigger is failing in two cases one update and delete when i am deleting a record its giving this

error  

pointamount: execution of AfterDelete caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.pointamount: line 5, column 31: []

 

and while update ting this part of code is not workin

    if(fn.size()==0)
                            {
                                points__c  a = new Points__c();
                                a.Account__c = o.Accountid;          
                                a.Points_Transaction_Amount__c =o.amount-o.amount*2;
                                a.Points_Transaction_Reason__c =' Points Redeemed';  
                                a.Points_Transaction_Date__c=o.CloseDate;
                                a.Purchaser_Email__c=o.Contact_Email__c;
                                a.Opportunity__c=o.id;
                                a.Purchaser_Name__c=o.Purchaser_Name__c;
                                insert a;  
                            }
 
can u pls look into  it

 

arishi0arishi0

Hello srikant,

 

Below is the code updated to be bulkified. Although I have had some difficulty uinderstanding some of your code. Specially this part:

 

Points__c[] fn =[select id,account__c,opportunity__c from Points__c where opportunity__c=:o.id];

 

and then here:

 

if(fn.size()>0{

fn[0].Points_Transaction_Amount__c=o.amount-o.amount*2;

 

 

 Basically you are getting a list of points for a given Opportunity, BUT then you only look at the first returned points record for the Opportunity and update only that one. Is this on purpose or do you actually want to update all the points for the Opportunity??

 

 

Anyhow, below is the bulkified code, I do hope it helps you.

trigger pointamount on Opportunity ( after insert,after update,before delete){
//add this list to hold points__c records to insert all at once.
List<points_c> points;
List<points__c> pointsDEL;

 if(trigger.isInsert)  {
	for (Opportunity  o : Trigger.new){ 
		if(o.accountid!=null && o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter'){
			points__c  a = new Points__c();
			a.Account__c = o.Accountid;          
			a.Points_Transaction_Amount__c =o.amount-o.amount*2;
			a.Points_Transaction_Reason__c =' Points Redeemed';  
			a.Points_Transaction_Date__c=o.CloseDate;
			a.Purchaser_Email__c=o.Contact_Email__c;
			a.Opportunity__c=o.id;
			a.Purchaser_Name__c=o.Purchaser_Name__c;
			points.add(a);
		}
	}
	Database.insert(points);
	points = null;
	//If you would prefer to insert the records and not have the DML transaction fail if one of the records insert fails then use this: Database.Insert(points,false); 
 }
 
 
  if(trigger.isupdate) {
  //WHY ARE YOU USING fn[0] to get the points?? This would only get the first record in the array, not any other if there are more than one.
	for (Opportunity  o : Trigger.new){
		if(o.accountid!=null && o.Purchase_Type__c == 'Pilot' && o.Catalog_Source__c == 'SimCenter'){
			Points__c[] fn =[select id,account__c,opportunity__c from Points__c where opportunity__c = :o.id];		
			
			if(fn.size()==0){
				points__c  a = new Points__c();
				a.Account__c = o.Accountid;          
				a.Points_Transaction_Amount__c =o.amount-o.amount*2;
				a.Points_Transaction_Reason__c =' Points Redeemed';  
				a.Points_Transaction_Date__c=o.CloseDate;
				a.Purchaser_Email__c=o.Contact_Email__c;
				a.Opportunity__c=o.id;
				a.Purchaser_Name__c=o.Purchaser_Name__c;
				points.add(a);
			}
			if(fn.size()>0){
				//I dont understand why you only look at the first record here( fn[0] ), do you not want to update ALL points records for the Opportunity??? 	
				fn[0].Points_Transaction_Amount__c = o.amount-o.amount * 2;
				points.add(a);
			} 
		}
	}
	//IF there are new points to insert for the Opportunities they will be inserted into database, if there are existing ones they will be updated
	if(points.size()> 1) Database.Upsert(points);
	
}

if(trigger.isdelete  ){
	for (Opportunity  o : Trigger.old){
		if(o.accountid!=null &&o.Purchase_Type__c == 'Pilot'&& o.Catalog_Source__c== 'SimCenter'){
			Points__c fn =[select id,account__c,opportunity__c from Points__c where opportunity__c=:o.id  ];
			pointsDEL.add(fn);
		}
	}
	Database.delete(pointsDEL);
}

}