You need to sign in to do that
Don't have an account?
Sammy7
insert invoice on opportunity from quote line item
Hi,
So I created a custom object Invoice__c and Invoicelineitem__c. Basically, I want to copy all the quote line items to invoice line items.
Below is my code:
trigger Insertnewinvoice on Invoice__c (after insert) {
Invoice__c to=trigger.new[0];
Quote q=[Select id from Quote where id= :to.Quote__c];
list<QuoteLineItem> ql=[select id,ListPrice,PriceBookEntry.Product2Id ,Subtotal,TotalPrice from QuoteLineItem where QuoteId=:q.id];
for(QuoteLineItem qli:ql){
Invoicelineitem__c lm=new Invoicelineitem__c();
lm.List_Price__c=qli.ListPrice;
lm.Product__C=qli.PriceBookEntry.Product2Id;
lm.Order__c=to.id;
insert lm;}}
Why am I getting error: "unexpected token 'Select id from Quote where id' ??
So I created a custom object Invoice__c and Invoicelineitem__c. Basically, I want to copy all the quote line items to invoice line items.
Below is my code:
trigger Insertnewinvoice on Invoice__c (after insert) {
Invoice__c to=trigger.new[0];
Quote q=[Select id from Quote where id= :to.Quote__c];
list<QuoteLineItem> ql=[select id,ListPrice,PriceBookEntry.Product2Id ,Subtotal,TotalPrice from QuoteLineItem where QuoteId=:q.id];
for(QuoteLineItem qli:ql){
Invoicelineitem__c lm=new Invoicelineitem__c();
lm.List_Price__c=qli.ListPrice;
lm.Product__C=qli.PriceBookEntry.Product2Id;
lm.Order__c=to.id;
insert lm;}}
Why am I getting error: "unexpected token 'Select id from Quote where id' ??
All Answers
Hi Sammy,
I made some adjustments to your trigger. Some tips for you:
Avoid putting DML Statements in your for loop as you can hit governor limits if your trigger list is large enough.
Try to bulkify your code by acting on the entire trigger list and not just on the first element of the list.
Also the query for quote is unnecessary since you already have the Id in the lookup.
Try this code out.
Hope this helps!
AM
Could the unexpected token be that there is no master-detail to Quotelineitem ??
Can you please see my comments below. I really apperciate the help here:
So this trigger is actually a bit more complicated than I thought. If I'm understanding this correctly your data model is like this:
QuoteLineItem belongs to Quote.
Invoice belongs to Quote.
InvoiceLineItem belongs to Invoice.
For each QuoteLineItem that belongs to a quote, you want to create an InvoiceLineItem for ALL invoices that belongs to the quote. This means that if a quote has 5 QuoteLineItems, and you insert 5 Invoices at the same time to one quote, you will end up with 25 InvoiceLineItems.
I've modified the trigger to facilitate this logic:
Let me know if this works!
Basically, I want the quote along with its quotelineitems to pass to invoice__c and its invoicelineitems__c.
For instance, if quote A has 2 lineitems, then I want the same Invoice A with 2 line items
So lets say when opportunity == closed, then create the invoice along with the invoicelineitems from the quote and corresponding quotelineitems.
I guess this is my pseudo code for the trigger:
//Then I guess the trigger should be on opportunity instead?
trigger Insertnewinvoice on opportunity (after insert) {
Set <id> oppid= new set<id> ();
List<Invoice__c> Invoicelist = new List<Invoice__c>();
List<Invoicelineitem__c> InvoicelineitemList = new List<Invoicelineitem__c>();
//get all the new closed opps and add to set oppid
for (opportunity o: Trigger.new) {
if(o.isclosed==true) { oppid.add (o.id) }
for (Opportunity opp:oppid) {
//getquoteids
list<Quote> qid =[select id From quote where .....] // not sure of syntax but need the quoteids belonging to that closed opportunity
//get the quotelineitemlist
list<QuoteLineItem> quoteLineItemList =[select id,ListPrice,PriceBookEntry.Product2Id ,Subtotal,TotalPrice, QuoteId from QuoteLineItem where ...]
//this is tricky, I dont want to mix the line items from two separate quotes....how to accomplish this?
//create the invoice for each quote
for(quote q: qid) {
Invoice__c inv= new invoice__c ();
inv.invoicenumber= q.number ; //copy over the quote number
invoicelist.add (inv);
//finally create those invoicelineitems
for(quotelineitem qli: quotelineitemlist) {
Invoicelineitem__c ili= new invoicelineitem__c();
ili.List_price__c= qli.ListPrice;
ili.Product_Code__c= qli.Pricebookentry.Product2id;
Invoicelineitemlist.add (ili);
}
}
}
insert invoicelist;
insert invoicelineitemlist;
}
// Its getting late, but I just had another thought... Quote and quotelineitem are in a relationship and I have invoice and invoicelineitem in a relationship...
so I should be able to traverse, for instance invoice__c.invoicelineitem__c.List_price__c= quote.quotelineitem.Listprice ??
This way the invoice and invoicelineitems stay grouped like quotes and quotelineitems. Any help is appreciated as Im learning this as I go and my job does depend on this :(
Thanks.
So now I understand your data model. It looks like you have Quotes and Invoices both belonging under Opportunities, and QuoteLineItems and InvoiceLineItems under those, respectively.
So the logic is, everytime an opportunity is updated to be closed, you want to insert one invoice per quote and one invoicelineitem per quotelineitem. You also need to maintain the same relationship between quotes/quotelineitems and invoice/invoicelineitems.
This trigger is actually kind of complicated... I tried to put a lot of comments. I just tested this on my own org, and it works fine. Let me know how it works out for you.
Error:Apex trigger CreateInvoice caused an unexpected exception, contact your administrator: CreateInvoice: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Invoice]: [Invoice]: Trigger.CreateInvoice: line 30, column 1