You need to sign in to do that
Don't have an account?
Paul Kim 24
Clone Opportunity Line Item to Quote Line Items
Hey everyone,
New to APEX so I apologize if my question doesn't have enough information to start to accurately portray my question.
The problem I'm trying to solve is that on Opportunities, we're currently using Products. I'd like for the Opportunity Stage Name of "Closed Pending" to 1. create a Quote and then 2. then take all of the Opportunity Products and clone them onto the Quote as Quote Line Items - keeping in mind that the Products are the same for both the Quote and the Opportunity. Here's my code:
This is to create the Quote at the point of Stage = Closed Pending (isPending is a formula checkbox for when Stage is Closed Pending, so may be redundant?)
Any help would be greatly appreciated!
New to APEX so I apologize if my question doesn't have enough information to start to accurately portray my question.
The problem I'm trying to solve is that on Opportunities, we're currently using Products. I'd like for the Opportunity Stage Name of "Closed Pending" to 1. create a Quote and then 2. then take all of the Opportunity Products and clone them onto the Quote as Quote Line Items - keeping in mind that the Products are the same for both the Quote and the Opportunity. Here's my code:
This is to create the Quote at the point of Stage = Closed Pending (isPending is a formula checkbox for when Stage is Closed Pending, so may be redundant?)
trigger CreateQuote on Opportunity (after update) { List<Opportunity> o = new List <Opportunity>(); o = [SELECT ID FROM Opportunity WHERE StageName = 'Closed Pending']; for (Opportunity opp: Trigger.new) { if(opp.isPending__c ==true){ Quote newQuote = new Quote(); newQuote.Name = opp.Name + ' Quote'; newQuote.OpportunityId = opp.Id; insert newQuote; } } }Here's the second trigger where I attempt to clone the Opportunity Products:
trigger QuoteLineItem on Quote (after insert) { Quote q=trigger.new[0]; Opportunity oppID=[SELECT id FROM Opportunity WHERE id=:q.OpportunityId /*AND StageName = 'Closed Pending'*/]; List<OpportunityLineItem> opplines=[SELECT id, PricebookEntryId, Product2ID, Quantity, UnitPrice, ARR__c FROM OpportunityLineItem WHERE OpportunityId=:oppID.id]; for(OpportunityLineItem oppline:opplines){ QuoteLineItem qli = new QuoteLineItem(); qli.QuoteId = q.id; qli.Product2Id = oppline.PriceBookEntry.Product2Id; qli.Quantity = oppline.Quantity; qli.ARR__c = oppline.ARR__c; qli.UnitPrice = oppline.UnitPrice; insert qli; } }
Any help would be greatly appreciated!
Please mark this as best if this solution works.
Thank you so much for the help! This is immensely helpful for getting me on the right track, especially the use case of Map vs List.
After inserting your code and deactivating the "QuoteLineItem" trigger, when I change the Opportunity Stage to "Closed Pending", the following is the error:
Error:Apex trigger SyncQuoteOppTrigger caused an unexpected exception, contact your administrator: SyncQuoteOppTrigger: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Price Book Entry]: [Price Book Entry]: Trigger.SyncQuoteOppTrigger: line 29, column 1
I can't seem to figure out the required field that I'm missing however.