function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
emuelasemuelas 

Trigger to get Quote Line Items into custom object

Hi,

 

Iam  new to Apex.I have  custom objects Order and Order Line Items (master detail).The order line items appears as a related list under the Order object.

 

Whenever an order is created from the quote,the quoteline items should be inserted as order line items ....This functionality is just like how the opportunity products are inserted as quote line items whenever a new quote is created from the opportunity.

 

Is it possible to do this using a trigger?

 

If yes ,can i please have some pointers to any sample trigger code that does this kind of insert from a related list of the master object to the related list of the detail object

 

Thanks!

Best Answer chosen by Admin (Salesforce Developers) 
Ispita_NavatarIspita_Navatar

Yes the functionality you are trying to implement can be done via triggers.

 

Here a sample code:-

 

trigger test1 on Order__c (after insert)

{

Order__c to=trigger.new[0];

Quote q=[select id from Quote where id=:to.Quote__c];

QuoteLineItem ql=[select id,...,....,.. from QuoteLineItem where Quote=:q.id];

 

for(QuoteLineItem qli:ql)

{

OrderLineItem__c lm=new OrderLineItem__c();

lm.Email__c=qli.Email;

.....

.....

.....

 

lm.TestObject__c=qli.id;

insert lm;

}

 

Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved.

All Answers

Ispita_NavatarIspita_Navatar

Yes the functionality you are trying to implement can be done via triggers.

 

Here a sample code:-

 

trigger test1 on Order__c (after insert)

{

Order__c to=trigger.new[0];

Quote q=[select id from Quote where id=:to.Quote__c];

QuoteLineItem ql=[select id,...,....,.. from QuoteLineItem where Quote=:q.id];

 

for(QuoteLineItem qli:ql)

{

OrderLineItem__c lm=new OrderLineItem__c();

lm.Email__c=qli.Email;

.....

.....

.....

 

lm.TestObject__c=qli.id;

insert lm;

}

 

Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved.

This was selected as the best answer
emuelasemuelas

Sorry for the late reply...

 

Thanks Ispita!!!!!

 

i used the following code,but i still get errors:

trigger test1 on Sales_Order__c (after insert)

{

Sales_Order__c to=trigger.new[0];

Quote q=[select id from Quote where id=:to.Quote__c];

QuoteLineItem ql=[select id,List Price,Product,Quantity,Quote Name,Sales Price,Subtotal,Total Price from QuoteLineItem where Quote=:q.id];

 

for(QuoteLineItem qli:ql)

{

Order_Line__c lm=new Order_Line__c();

lm.Email__c=qli.Email;

lm.List_Price__c=qli.List Price;
lm.Product__C=qli.Product;


lm.Order_Line__c=qli.id;

insert lm;

}

 

 

 

I get the following error:

Error: Compile Error: No such column 'SalesPrice' on entity 'QuoteLineItem'.

Is the API names for the quote line items fields correct?

 

i tried to refer the salesforce help for the names.

 

Please help.

 

Thanks !!!!!

MikeGillMikeGill

I was completely stuck, until I read this post by

 

 

 

trigger createOrder on Opportunity (after update) {

    for (Opportunity opp: Trigger.new){
    
        Order__c newOrder = new Order__c();
        
        newOrder.Account__c = opp.AccountId;
        newOrder.Opportunity__c = opp.Id;
        newOrder.Total_Amount__c = opp.Amount;
        
        //Opportunity lines = [];
        
        insert newOrder;
    
    }

}

 

 

The second triiger is on the custom Order object

 

 

trigger createOrderDetails on Order__c (after insert) {

Order__c ord=trigger.new[0];

// Fetch Opp Id
Opportunity oppId=[select id from Opportunity where id=:ord.Opportunity__c];

// Fetch Opp Lines 
List<OpportunityLineItem> opplines=[select id, quantity, PriceBookEntry.Product2Id 
from OpportunityLineItem where OpportunityId=:oppId.id];

    // Loop Opportunity Lines
    for(OpportunityLineItem oppline:opplines){
        
        // Create Order Line Object
        Order_Line__c OrderLine = new Order_Line__C();
        OrderLine.Order__c = ord.Id;
        OrderLine.Product__c = oppline.PriceBookEntry.Product2Id;
        OrderLine.Quantity__c = oppline.Quantity;
        insert OrderLine;
    }

}

 

 

Obviously this doesn't have any exception handling and every save of opportunity creates an order. But it should move you in the right direction.

 

My questions for Ispita are

 

1. 

Order__c ord=trigger.new[0];

Why did you specify [0] element at the end?

 

2. I have my head round the trigger syntax but struggling with moving the code out to a class for better reusability. I guess it's just a question of playing and reading as much as possible. Any advice?

 

3. What's the best way to call my first trigger from a button e.g. Create Order

 

Really enjoying figuring things out. The platform is very impressive.

 

Mike

 

 

 

 

 
emuelasemuelas

Thanks a ton Ispita!!...

 

Thanks Mike for the inputs that helped me get this work...

 

My final code:

 

trigger test1 on Sales_Order__c (after insert)
{

Sales_Order__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)

{

Order_Line__c lm=new Order_Line__c();



lm.List_Price__c=qli.ListPrice;
lm.Product__C=qli.PriceBookEntry.Product2Id;


lm.Order__c=to.id;

insert lm;
}
}

Thanks Again!!!!!

Ispita_NavatarIspita_Navatar

Anytime ...u r all most welcome

Ispita_NavatarIspita_Navatar

Hi Mike,

Answer to your question no. 3.

In order to execute a trigger on the click of a trigger you need to update an instance of the object as then the trigger will automatically get invoked- so in summary fire a DML on the object and as a result the trigger will get invoked.

 

Answer to your question no. 2

Yes it is a question of practice, for a class generally you manipulate the parameters  passed to the respective function in class rather than refering to trigger.new or Trigger.old. as is done in a trigegr, plus all checks on if it is insert or update are not included.

 

Answer to question 1,

trigger.new[0] is used as in trigger mostly parameters are passed as an array and as I am just manipulating the first instance of the records submitted I use the 0th element.

 

Thanks

Ispita

 

 

MikeGillMikeGill

Thanks for advice, building my knowledgebase of best-practices.

 

Cheers,

 

Mike

sreelekhasreelekha

i have a problem to pass the quote total price to amount of opportunity  when adding bulky  quoteline items .How to solve this problem with out using queries in loop.Here is my code.

trigger qlitem on QuoteLineItem (after insert, after update) {
		
		List<opportunity> opl=new List<opportunity>();
		
		public static double total=0;
		List<quotelineitem> qlil=new List<quotelineitem>();
		Quote Q=new Quote();
		Opportunity opp=new Opportunity();
		
		for(quotelineitem qli:trigger.new){
		    //qlil.add(qli);
		
		Q= [Select id,opportunityid ,grandtotal,totalprice,primary__c from quote where id=:qli.quoteid];
		
		opp=[Select id, amount from Opportunity where id=:q.opportunityid];
	    
		    
		}
		for(integer i=0;i<qlil.size();i++){
			 total=total+qlil[i].TotalPrice;
		}
		if(q.primary__c){
			  
				//This logic is used for updating the amount of opportunity  with quote total price
				Opp.amount=q.totalprice+total ;
				
			}
			opl.add(opp);
		    
	 		update opl;
		
	    
		
}

 Thanks 

Sreelekha

 

sreelekhasreelekha

i tried this but i got compile error 

that is : Variable does not exist: q.opportunityid at line 59 column 41

Junior007Junior007

Hi,

 

Tried with the same trigger getting the Following Error

 

Error: Compile Error: sObject type 'QuoteLineItem' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names. at line 5 column 24

 

any help would be appreciated

kevin.chileskevin.chiles

Hello I am having a similar error.  It keeps stating that I have the Incorrect SObject type: SPA__c should be Quote and Line 1 column 1.  Does anyone have any ideas as to why this is happening?  Here is my code as it stands.  Use case is to bring over quote line items after SPA__c is created by a trigger from the Quote(generating the header information)  Then the line items should pull over as well from the same quote.

 

trigger test1 on SPA__c (after insert)
{

SPA__c to=trigger.new[0];

Quote q=[select id from Quote where id=:to.Volume_Price_Quote__c];

list<QuoteLineItem> ql=[select id,ListPrice,PriceBookEntry.Product2Id ,Subtotal,TotalPrice from QuoteLineItem where QuoteId=:q.id];

 

for(QuoteLineItem qli:ql)

{

SPA_Discount__c sd=new SPA_Discount__c();



sd.Net_Price__c=qli.ListPrice;
sd.SPA_Discount_for__c=qli.Product_Name__c;
sd.Public_Notes__c=qli.Public_Notes__c;
sd.Private_Notes__c=qli.Private_Notes__c;
sd.Sales_Commision_Split__c=qli.Sales_Commission_Split__c;
sd.Option_For_Split_Choice__c=qli.Option_For_Split_Choice__c;
sd.Spiff__c=qli.Spiff__c;


insert sd;
}
}