Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I'm trying to find out if a Quote Line Item has any reference back to which Opportunity Line Item it relates to. Does it??

The reason is that I have extra fields on the OLI which I need to pull into the QLI and so need to do something that can pull this info into the QLI. Ideally, I'd like a 'point and click solution' (e.g. workflow or formula) to do this - is it possible? I know I can work it out in a trigger using the Quote.Opportunity reference, the pricebook2id and other fields and look for a match but this feels like too much effort to do something simple.

Something like the 'Map Lead Fields' when converting a Lead would be ideal in this case...

share|improve this question
    
Have a look at this app exchange package, it's unmanaged so you can have a look at the code:appexchange.salesforce.com/… –  Girbot Aug 20 at 10:38

3 Answers 3

up vote 3 down vote accepted

As @PeterKnolle pointed out, there isn't a relationship.

Fortunately, there is a Force.com lab packages out there that can let you sync custom fields from opportunity line items to quote line items, we've been using it for a while without any major issues. It's rough if you look at the code, but considering the lack of maintenance it's very effective and bug free

share|improve this answer
    
If I remember correctly it doesn't support boolean fields out of the box. –  Girbot Aug 20 at 12:58
    
I'll press on with creating my own triggers/code to sync the OLI and QLI as some of the reviews on the AppExchange weren't too positive about the product. As a developer, part of the fun is coming up with your own solution to a common problem. Should only be a day of messing about... –  Richard Durrant Aug 20 at 19:57

QuoteLineItem does not have a direct reference back to OpportunityLineItem.

The Product and Schedule Objects ERD shows the relationships.

Products and Schedule Objects ERD

While both objects have a Lookup to PricebookEntry that does not relate them in a way that would allow you to get from QuoteLineItem to OpportunityLineItem, since on PricebookEntry could be related to multiple OrderLineItems (e.g., product added more than once, different unit prices).

Interestingly, the new OrderItem (Order Product) does have a Lookup to QuoteLineItem.

share|improve this answer
    
Thanks for you answer Peter - very interesting to see the OrderItem object. I would have enough information to associate each QLI with the OLI with the fields I have available - I will get coding tomorrow! –  Richard Durrant Aug 20 at 19:54

After a quick hack this works. Next to refactor, error handle and tidy up...

trigger triggerQLI on QuoteLineItem (before insert) {

    //get the quote record and find the Oppty and match on the OLI that caused the QLI to be created. Set the QLI's course field accordingly...
    //match on product (pricebook?), price and quantity

    set<id> quoteIds = new set<id>();

    for(QuoteLineItem QLI : trigger.new){
        quoteIds.add(QLI.QuoteId);
    }

    map<id,Quote> quotes = new map<id,Quote>([select id, OpportunityId from Quote where id in:quoteIds]);

    set<id> opptyIds = new set<id>();
    for(Quote q : quotes.values()){
        opptyIds.add(q.OpportunityId);
    }

    map<id,Opportunity> opptys = new map<id,Opportunity>([select id, name, (select id, Course__c, OpportunityId,PricebookEntryId,Product2Id,Quantity,UnitPrice from OpportunityLineItems) from Opportunity where id in:opptyIds]);



    for(QuoteLineItem QLI : trigger.new){
        id opptyId = ((Quote)quotes.get(QLI.QuoteId)).OpportunityId;

        Opportunity oppty = opptys.get(opptyId);

        for(OpportunityLineItem OLI : oppty.OpportunityLineItems){
            if(OLI.Product2Id == QLI.Product2Id && OLI.Quantity == QLI.Quantity && QLI.UnitPrice == QLI.Unitprice){
                    //SET THE QLI FIELDS HERE AS NECESSARY
                    QLI.Course__c = OLI.Course__c;
                    break;
                }
        }

    }

}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.