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 

help for trigger soql limit

hi all

 i have written this trigger but in sandbox its working but in live its giving errors plz some one help me rewr

public class updateasset1 {
public static boolean isfuture=false;
public static void oli (OpportunityLineItem[] OLI)
      {
     if (isfuture==false){
     isfuture=true;
   // for(OpportunityLineItem ol: OLI){  
   OpportunityLineItem ol = OLI[0];
 ol = [Select UnitPrice,OpportunityId, Opportunity.Account.Id , Quantity,Fully_Shipped_Date__c,Shipped_Quantity__c, PricebookEntry.Product2Id,Create_Asset__c, PricebookEntry.Product2.Name,Product_Shipment_Status__c, Description From OpportunityLineItem where OpportunityLineItem.Id = :ol.Id limit 1]; 

        Asset[] ast = new Asset[]{}; 
        Asset a = new Asset();        
 
 
 
 
 
 
if(ol.Product_Shipment_Status__c == 'Fully Shipped'&& ol.Create_Asset__c == false){ 

        
a = new Asset();   
a.Name = ol.PricebookEntry.Product2.Name;
a.Asset_Location__c =   'NONE' ;
a.AccountId = ol.Opportunity.Account.Id;            
a.Product2Id = ol.PricebookEntry.Product2Id;          

a.PurchaseDate =ol.Fully_Shipped_Date__c;
a.Quantity = ol.Quantity;
a.Price = ol.UnitPrice;
     
ast.add(a);           
ol.Create_Asset__c = true;  
 

  update OL; 
}
    
upsert ast;  
}
//}   
 }   
 }
trigger updateasset1 on OpportunityLineItem (after update) {OpportunityLineItem[] OLI = Trigger.new;
updateasset1.oli(OLI);
}
plz help me resolve the issue

 

 

ite the code to avoid the errors

 

 

markdamomarkdamo

You are running a database query within a For loop.  

 

What you need to do is to store the IDs in a ID set and then run another query outside of the For loop to lookup ids in the ID set.

 

Set<Id> accIds= new Set<Id>();
for (Opportunity opp:trigger.new){
  accIds.add(opp.AccountId);
}

//If you had IDs in the ID set do the following
if(accIds.size()>0){
for(Account a : [select id, type from Account where id in :accIds]) {
  //Do some processing
}

 

Shashikant SharmaShashikant Sharma

I think you commented for loop as it was causing you issue , if so then uncooment and chnage that part of code like this

 

MAP<ID,OpportunityLineItem> mapOpportunityLineItem = new Map<ID,OpportunityLineItem>([Select UnitPrice,OpportunityId, Opportunity.Account.Id , Quantity,Fully_Shipped_Date__c,Shipped_Quantity__c, PricebookEntry.Product2Id,Create_Asset__c, PricebookEntry.Product2.Name,Product_Shipment_Status__c, Description From OpportunityLineItem where OpportunityLineItem.Id in: OLI]

for(OpportunityLineItem ol: OLI){  
   
 ol = mapOpportunityLineItem.get(ol.Id);

        Asset[] ast = new Asset[]{}; 
        Asset a = new Asset();  

 

srikanth11srikanth11

your answer  helped me shasikanth sharma . sir my trigger is calling other triggers and the soql query limit is increasing may be its occuring when upserting opportunity line items so how can i maake my trigger so that it does not call other triggers

Shashikant SharmaShashikant Sharma

you can use a static variable for this use that as in condition over all the triggers that you do't want to get executed.

 

see this example in my blog : http://forceschool.blogspot.com/2011/05/writing-apex-trigger-issues-and_24.html

 

let me know if any issue in implementing this.

srikanth11srikanth11

sir  i read u r blog its very usefull i rewrite my code using u r help  but now at what part should i we set the static variable false

 

public class updateasset1 {
public static boolean isfuture=false;
 
public static void oli (OpportunityLineItem[] OLI)
      {
     if (isfuture==false){
     isfuture=true;
     
     
  MAP<ID,OpportunityLineItem> mapOpportunityLineItem = new Map<ID,OpportunityLineItem>([Select UnitPrice,OpportunityId, Opportunity.Account.Id , Quantity,Fully_Shipped_Date__c,Shipped_Quantity__c, PricebookEntry.Product2Id,Create_Asset__c, PricebookEntry.Product2.Name,Product_Shipment_Status__c, Description From OpportunityLineItem where OpportunityLineItem.Id in: OLI]);

for(OpportunityLineItem ol: OLI){  
   
 ol = mapOpportunityLineItem.get(ol.Id);

        Asset[] ast = new Asset[]{}; 
        Asset a = new Asset();         
 
 
 
 
 
 
if(ol.Product_Shipment_Status__c == 'Fully Shipped'&& ol.Create_Asset__c == false){ 

        
a = new Asset();   
a.Name = ol.PricebookEntry.Product2.Name;
a.Asset_Location__c =   'NONE' ;
a.AccountId = ol.Opportunity.Account.Id;            
a.Product2Id = ol.PricebookEntry.Product2Id;          

a.PurchaseDate =ol.Fully_Shipped_Date__c;
a.Quantity = ol.Quantity;
a.Price = ol.UnitPrice;
     
ast.add(a);           
ol.Create_Asset__c = true;  
 

  update OL; 
}
    
upsert ast;  
}
}   
 }   
 }

 

Shashikant SharmaShashikant Sharma

In that example thre were three steps

1)Creating a Class with static variable

2)Adding that to trigger

3)Setting the value to false in class

 

So as you finished first two so now you just need to put it like where you are inserting opportunity line item as you have a trigger on this object

 

Constants.runTrigger = false;

update OL;

 

srikanth11srikanth11

sir my test case i am writing for this is giving dml exceprtion plz help me with it

 

 

@isTest
private class updateassetTestSuite {
static testMethod void validateabc() {
Pricebook2 standardPB = [select id from Pricebook2 where isStandard=true];



  Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true);      
    insert pb;               
   Product2 prod = new Product2(Name = 'Anti-infectives 2007', Family = 'Best Practices', IsActive = true);      
    insert prod;      
   PricebookEntry standardPrice = new PricebookEntry(Pricebook2Id = standardPB.Id, Product2Id = prod.Id, UnitPrice = 10000, IsActive = true, UseStandardPrice = false);       
     insert standardPrice;   
  PricebookEntry pbe = new PricebookEntry(Pricebook2Id = pb.Id,Product2Id = prod.Id,   UnitPrice = 10000, IsActive = true, UseStandardPrice = false);  
        insert pbe;

Account a = new Account();
 a.name = 'raja'; 
 insert a ;

Opportunity opp = new Opportunity(); 
opp.Name = 'raja'; opp.probability=5; 
opp.StageName = 'Billing-Planned'; 
 
 
 opp.CloseDate = date.ValueOf('2009-09-21'); 
 opp.Pricebook2Id = pb.id; 
  opp.ForecastCategoryName='pipeline';  
   insert opp;

        OpportunitylineItem opli = new OpportunitylineItem(); 
         opli.opportunityid=opp.id; 
         opli.TotalPrice=5;  
         opli.quantity=3;  
       opli.Product_Shipment_Status__c ='Approved';
          opli.PricebookEntryId = pbe.id; 
       insert opli;

 Asset a1 = new Asset();       
 

a1.Name = 'ffg';
a1.Asset_Location__c =   'NONE' ;
a1.AccountId = a.id;            
a1.Product2Id = opli.PricebookEntry.Product2Id;          

a1.PurchaseDate =date.ValueOf('2009-7-21');
a1.Quantity =4;
a1.Price = 7;
 insert a1;
 
 
 
 
 

}
}
its giving this error
System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, The Status has to be Approved: []
plz help me resolve this issue

 

Shashikant SharmaShashikant Sharma

Check the validation rule , you must be having one which verifies status, do you set status in the trigger that you have blocked using static variable? Please let me knwo in which line you are getting and on which object.

IN case you have trouble in tracing please share your final trigger code both that you blocked and this one in which you have set sataci variable to false.

srikanth11srikanth11

sir i am getting errors in setting the static variable to false i think i have written the class and giving it to trigger in wrong way plz help me with it sir