You need to sign in to do that
Don't have an account?

How to insert a quote and a quoteLineItem when an opportunity is cloned with products ?
I would like to create a trigger which can insert a quote and a quotelineitem when I clone an opportunity with its product. I tried many Trigger.
If someone can help me understand the problem it would be awesome! I spent already a few days on it...
trigger FacturationCreator on Opportunity (after insert, after update) {
for (Opportunity o : Trigger.new) {
if (o.Type == 'Event') {
//Opportunity oppId=[select id from Opportunity where id=:q.OpportunityId];
List<OpportunityLineItem> opplines=[select id, quantity, PriceBookEntry.Product2Id, UnitPrice, PricebookentryId
from OpportunityLineItem where OpportunityId=:o.id];
for(OpportunityLineItem oppline:opplines){
List <Quote> factList = new List<Quote>();
Quote q = new Quote();
q.name = 'Quote-' + o.name;
q.Montant_1_re_ch_ance__c = 1000;
q.Date_de_Facture__c = o.CloseDate;
q.Date_1_re_ch_ance__c = o.CloseDate;
q.opportunityId = o.id;
factList.add(q);
insert q;
List<Quote> qList=[select id from Quote where opportunityId=:o.id];
for(Quote q:qList){
QuoteLineItem qli = new QuoteLineItem();
qli.quoteId = q.Id;
qli.UnitPrice = oppline.UnitPrice;
qli.Product2Id = oppline.PriceBookEntry.Product2Id;
qli.Quantity = oppline.Quantity;
qli.PriceBookentryid = oppline.PriceBookentryId;
insert qli;}
}
}
}
}
If someone can help me understand the problem it would be awesome! I spent already a few days on it...
trigger FacturationCreator on Opportunity (after insert, after update) {
for (Opportunity o : Trigger.new) {
if (o.Type == 'Event') {
//Opportunity oppId=[select id from Opportunity where id=:q.OpportunityId];
List<OpportunityLineItem> opplines=[select id, quantity, PriceBookEntry.Product2Id, UnitPrice, PricebookentryId
from OpportunityLineItem where OpportunityId=:o.id];
for(OpportunityLineItem oppline:opplines){
List <Quote> factList = new List<Quote>();
Quote q = new Quote();
q.name = 'Quote-' + o.name;
q.Montant_1_re_ch_ance__c = 1000;
q.Date_de_Facture__c = o.CloseDate;
q.Date_1_re_ch_ance__c = o.CloseDate;
q.opportunityId = o.id;
factList.add(q);
insert q;
List<Quote> qList=[select id from Quote where opportunityId=:o.id];
for(Quote q:qList){
QuoteLineItem qli = new QuoteLineItem();
qli.quoteId = q.Id;
qli.UnitPrice = oppline.UnitPrice;
qli.Product2Id = oppline.PriceBookEntry.Product2Id;
qli.Quantity = oppline.Quantity;
qli.PriceBookentryid = oppline.PriceBookentryId;
insert qli;}
}
}
}
}
Apex class :
All Answers
IMHO it should be only for after insert, because if you clone an opportunity you only insert records.
This is what I would do.
This code might not be 100% perfect, but close to it though.
Actually, the 'after update' was a mistake and a consequence of many tries. Indeed, it shouldn't be there.
I tried what you posted which seems quite perfect, but unfortunately something is wrong...
It is null because at least one opportunity does not have any OLIs.
I did not expect this situation. So here we just have to create QLIs only if there is at least one OLI (which means we just have to check that lstOlis is not null).
That would result the following :
If you don't, it's not gonna work
At line 13 put :
And check in the Logs in the Developer Console.
Size should not be 0.
keep this window open
then clone a new opportunity
come back to this window and a new log will have appeared
double-click on the log
then search for ###
Do the same for oppIds
System.debug('### oppIds contains : ' + oppIds);
This list should contain at least one id, the id of the new Opportunity
Now I understand what is going on.
Your trigger is executed just after the new Opportunity is created, but just before the OLIs are created, so it doesn'find them.
My idea is that you will have to move all your code to a @future block so that it gets executed in the future.
By that time the OLIs should be available.
Apex class :
You might have to wait a few seconds to see the quote and the QLI
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_future.htm
Few seconds after you clone the Opportunity, a new log called FutureHandler or something like that shouls appear in the logs.
At that time Quote should be created.
If not, do some debugging.
I have never seen this message before.
Did you google the error message?
Many people have had the same issue as you.
At what line number does the issue appear? You didn't post the full stack trace of the message.
In the log you should see the line number.
In my opinion, it looks like the issue appears when you insert the QLI.
And for the QLI whe choose the same Pricebook Entry as the OLI :
qli.PriceBookentryid = oli.PriceBookentryId;
I think the PriceBookENtry specified here does not belong to Pricebook that is set at the level of Quote, hence the error.
So maybe you can try putting by default the same Pricebook for the Quote as the one that was assigned to the Opportunity.
Which means at line 34 you would add:
q.Pricebook2Id= o.Pricebook2Id;