You need to sign in to do that
Don't have an account?
I Can't insert an OpportunityLineItem from a trigger.
My use case is that, when a rep inserts an "Advanced" product (product code 99997) on and opportunity, I have to look at all the opportunities on the related account, and see if a "Basic" product is also on an opportunity on the account (product code 99998).
If not, I need to insert an OpportunityLineItem record with the Basic product.
What's weird to me is that, after building and inserting the OpportunityLineItem and putting it in the correct Opportunity (the one being edited), the 'before' and 'after' debug statements show no change to the number of opportunitylineitems.... This seems very strange to me.
Does anyone have a clue as to what may be happening? Is it even possible to programmatically add opportunitylineitems?
Thanks,
trigger CheckOpportunityForProperProducts on OpportunityLineItem (after insert) { Set<Id> accIdList = new Set<Id>(); List<Id> oppIdList = new List<Id>(); // Get Pricebook info for later (possible) insert Pricebook2 standardBook = [SELECT Id FROM Pricebook2 WHERE IsStandard = true]; PricebookEntry BasicEntry = [SELECT Id, UnitPrice FROM PricebookEntry WHERE Pricebook2Id = :standardBook.Id AND Product2.ProductCode = '99998']; //All opportunity IDs in a list for(OpportunityLineItem oli :Trigger.new) { oppIdList.add(oli.OpportunityId); } // this gives us just the account IDs related to this insert... List<Opportunity> tmpOpps = [SELECT Id, AccountId FROM Opportunity WHERE Id in :oppIdList]; List<Opportunity> updateTheseOpportunities = new List<Opportunity>(); for(Opportunity o :tmpOpps) { accIdList.add(o.AccountId); } // Now get the complete set of working data Map<Id, Opportunity> allOpps = new Map<Id, Opportunity> ([SELECT Id, AccountId, StageName, CreatedDate, Type, CloseDate, Name, (SELECT Quantity, UnitPrice, TotalPrice, PricebookEntry.Name, PricebookEntry.Product2.ProductCode FROM OpportunityLineItems) FROM Opportunity WHERE AccountId in :accIdList AND StageName LIKE '%Stage 5:%' AND Count_of_Products__c > 0 ORDER BY CreatedDate ASC]); for(Id acctId :accIdList) { Boolean AdvancedRuleFound = false; Boolean BasicRuleFound = false; Id theOppId = null; for(Opportunity o :allOpps.values()) { if(o.OpportunityLineItems != null && o.AccountId == acctId) { // oppty related to this account // check all oppty products on this account for(OpportunityLineItem opptyLineItem : o.OpportunityLineItems) { if(opptyLineItem.PricebookEntry.Product2.ProductCode == '99997') { // Advanced AdvancedRuleFound = true; theOppId = o.Id; // put on the same opportunity that the Advanced is on.... } if(opptyLineItem.PricebookEntry.Product2.ProductCode == '99998') { // Basic BasicRuleFound = true; } } // end of sifting thru olis } // END check for OpportunityLineItems } // END for(Opportunity o :allOps) System.debug('allOpps.get(theOppId).OpportunityLineItems.size() - Before: ' + allOpps.get(theOppId).OpportunityLineItems.size()); if(BasicRuleFound== false && AdvancedRuleFound == true && theOppId != null) { // need to insert the basic product... OpportunityLineItem oppli = new OpportunityLineItem(PricebookEntryId=BasicEntry.Id, OpportunityId=theOppId, UoM__c='Each', NRC__c = 1000, UnitPrice=0, Quantity=1); allOpps.get(theOppId).OpportunityLineItems.add(oppli); System.debug('allOpps.get(theOppId).OpportunityLineItems.size() - After: ' + allOpps.get(theOppId).OpportunityLineItems.size()); updateTheseOpportunities.add(allOpps.get(theOppId)); } } //upsert updateTheseOpportunities; }
Not sure if I got it right but try this:
Let me know if it worked.
Regards.
Don't forget to mark your thread as 'SOLVED' with the answer that best helps you.
Close, but the culprit was I needed to insert the OpportunityLineItem directly - basically like this;
...But I gave you a thumbs up for effort - and thanks for the prompt reply..... I hope to return the favor some day :-)