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
NikiG22NikiG22 

My Automatically Created Line Item is doubling?

Hello - i have some code here that will automaticlly create a new line item on an object called Ad Product Fulfillment when a closed won opp has a specific product. 

 

The problem is that it is doubling the line items isted of inserting the quantity. So insted of getting 1 i get 2?

 

Please help!

trigger trg_new_AdProductFulfillment on Opportunity (after update)
{
   List<Opportunity> closedWonOpps=new List<Opportunity>();

   for (Opportunity opp : trigger.new)
   {
       Opportunity oldOpp=trigger.oldMap.get(opp.id);
       if ( (opp.StageName=='Closed Won') &&
            (oldOpp.StageName!='Closed Won')) 
       {
          closedWonOpps.add(opp);
       }
   }
    
   if (!closedWonOpps.isEmpty())
   {
    List<OpportunityLineItem> olis = [SELECT ID, OpportunityId,Opportunity_Owner_id__c,PO_IO_Number__c, Account_ID__c,Standard_RateproductID__c,Closed_Won_Date__c,
        Quantity FROM OpportunityLineItem WHERE Ad_Product_Fulfillment__c ='True' and
        OpportunityId in :closedWonOpps];

    List<Ad_Product_Fulfillment__c> afToInsert=new List<Ad_Product_Fulfillment__c>();
   for (OpportunityLineItem oli : olis)
   {
    
    For (integer i = 0; i < oli.Quantity; i++){
            Ad_Product_Fulfillment__c newaf= new Ad_Product_Fulfillment__c();
            newaf.Opportunity__c = oli.Opportunityid;
            newaf.Placement__c = oli.Standard_RateproductID__c;
            newaf.Account__c = oli.Account_ID__c;
            newaf.IO_Start_Date__c = oli.Closed_Won_Date__c;
            newaf.PO_IO_Number__c = oli.PO_IO_Number__c;
            newaf.Quantity__c = oli.Quantity;
            newaf.Expiration_Date__c = oli.Closed_Won_Date__c +365;
            newaf.Account_Executive__c = oli.Opportunity_Owner_id__c;
            afToInsert.add(newaf);
        }
    }

    insert afToInsert;
   }
}

 Cheers,

Niki

Best Answer chosen by Admin (Salesforce Developers) 
Andy BoettcherAndy Boettcher

Niki,

 

Quick change to your code - you're doing a secondary loop against the Quantity Field instead of the row count, that's why you're getting multiple rows.

 

For (OpportunityLineItem oli : olis ){
// You don't need the inner loop Ad_Product_Fulfillment__c newaf= new Ad_Product_Fulfillment__c(); newaf.Opportunity__c = oli.Opportunityid; newaf.Placement__c = oli.Standard_RateproductID__c; newaf.Account__c = oli.Account_ID__c; newaf.IO_Start_Date__c = oli.Closed_Won_Date__c; newaf.PO_IO_Number__c = oli.PO_IO_Number__c; newaf.Quantity__c = oli.Quantity; newaf.Expiration_Date__c = oli.Closed_Won_Date__c +365; newaf.Account_Executive__c = oli.Opportunity_Owner_id__c; afToInsert.add(newaf); } }

-Andy

All Answers

Anup JadhavAnup Jadhav

The trigger looks okay to me. Can you enable debug logs, and see if the trigger is called more than once when it is run? i.e. insert a new line item in turn somehow fires the update trigger on opp. 

 

The order of execution(http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm) states that if the record is updated with workflows, field updates etc it will run the before and after trigger one more time (and only one more time).

 

Regards,

Anup

Andy BoettcherAndy Boettcher

Niki,

 

Quick change to your code - you're doing a secondary loop against the Quantity Field instead of the row count, that's why you're getting multiple rows.

 

For (OpportunityLineItem oli : olis ){
// You don't need the inner loop Ad_Product_Fulfillment__c newaf= new Ad_Product_Fulfillment__c(); newaf.Opportunity__c = oli.Opportunityid; newaf.Placement__c = oli.Standard_RateproductID__c; newaf.Account__c = oli.Account_ID__c; newaf.IO_Start_Date__c = oli.Closed_Won_Date__c; newaf.PO_IO_Number__c = oli.PO_IO_Number__c; newaf.Quantity__c = oli.Quantity; newaf.Expiration_Date__c = oli.Closed_Won_Date__c +365; newaf.Account_Executive__c = oli.Opportunity_Owner_id__c; afToInsert.add(newaf); } }

-Andy

This was selected as the best answer
NikiG22NikiG22

Thank you Andy!

 

Here is my complete code:

trigger trg_new_AdProductFulfillment on Opportunity (after update)
{
   List<Opportunity> closedWonOpps=new List<Opportunity>();

   for (Opportunity opp : trigger.new)
   {
       Opportunity oldOpp=trigger.oldMap.get(opp.id);
       if ( (opp.StageName=='Closed Won') &&
            (oldOpp.StageName!='Closed Won')) 
       {
          closedWonOpps.add(opp);
       }
   }
    
   if (!closedWonOpps.isEmpty())
   {
    List<OpportunityLineItem> olis = [SELECT ID, OpportunityId,Opportunity_Owner_id__c,PO_IO_Number__c, Account_ID__c,Standard_RateproductID__c,Closed_Won_Date__c,
        Quantity FROM OpportunityLineItem WHERE Ad_Product_Fulfillment__c ='True' and
        OpportunityId in :closedWonOpps];

    List<Ad_Product_Fulfillment__c> afToInsert=new List<Ad_Product_Fulfillment__c>();
   for (OpportunityLineItem oli : olis)
   {
    
    
            Ad_Product_Fulfillment__c newaf= new Ad_Product_Fulfillment__c();
            newaf.Opportunity__c = oli.Opportunityid;
            newaf.Placement__c = oli.Standard_RateproductID__c;
            newaf.Account__c = oli.Account_ID__c;
            newaf.IO_Start_Date__c = oli.Closed_Won_Date__c;
            newaf.PO_IO_Number__c = oli.PO_IO_Number__c;
            newaf.Quantity__c = oli.Quantity;
            newaf.Expiration_Date__c = oli.Closed_Won_Date__c +365;
            newaf.Account_Executive__c = oli.Opportunity_Owner_id__c;
            afToInsert.add(newaf);
          }

    insert afToInsert;
   }
}