[SalesForce] Trigger On Order to get Opportunity Line Item from opportunity to add in orderlineitem11

My requirement is that I am trying to create a trigger which is after insert and after update whenever i create order the opportunity line item will be added to the order line item. I have created lookup relationship from order to opportunity.

But when I am trying to edit and save the order object order items are updating with same names, ex: opportunity line item has two products like A,B when I am edit and save order items are updating A,B,A,B. Again when I edit and save order items are updating like A,B,A,B,A,B.

My requirement is to create line items only once with same name, and if different product is added like A,B,C. C product should be added to the order items when I edit and save order object. Can anyone help me

trigger creatingMenuDetails on Order (after insert, after update)
{
    // Get all related opportunities from orders
    Set<Id> opportunityIds = new Set<Id>();
    List<Order> orderList = new List<Order>();
    for(Order o : Trigger.new)
    {
        if(o.Opportunity__c != NULL)
        {
            opportunityIds.add(o.Opportunity__c);
            orderList.add(o);
        }
    }

    // Query for all opportunities with their related opportunity line items
    Map<Id, Opportunity> oppsWithLineItems = new Map<Id, Opportunity>([SELECT Id, (SELECT Description,Id,ListPrice,Name,OpportunityId,Product2Id,ProductCode,Quantity,TotalPrice,UnitPrice FROM OpportunityLineItem) WHERE Id IN :opportunityIds]);

    if(opportunityIds.size() > 0)
    {
        // Loop through orders
        List<OrderItem> orderItemsForInsert = new List<OrderItem>();
        for(Order o : ordersList)
        {
            // For each order get the related opportunity and line items, loop through the line items and add a new order line item to the order line item list for each matching opportunity line item
            Opportunity oppWithLineItem = oppsWithLineItems.get(o.Opportunity__c);
            for(OpportunityLineItem oli : oppWithLineItem.OpportunityLineItems)
            {
                orderItemsForInsert.add(new OrderItem(AvailableQuantity=Quantity,OrderId=o.Id,etc,etc,etc));
            }
        }
        // If we have order line items, insert data
        if(orderItemsForInsert.size() > 0)
        {
            insert orderItemsForInsert;
        }
    }
}

Best Answer

The reason you are getting duplicates is because when you insert the OrderItem (on after insert), this causes an OOTB roll up summary (on Order.TotalAmount) to execute on parent Order that then causes the on after update sequence to fire.

Or, you may have PB or WFR on Order that updates the Order once it is inserted (and hence on after update fires (again). Or you may have custom RSF or DLRS on Order:OrderItem

How you resolve this is application specific but at first blush, the approach might be

  • When Order is created, copy the OpportunityLineItem
  • When OpportunityLineItems are changed (added/updated/deleted), resync to OrderItem (presumably once Opportunity is closed, this can't happen)