At the time of this project, when a Quote is created from the Salesforce UI (Classic or Lightning), or the Quote is syncing, and you create an OpportunityLineItem (that is, add an Opportunity Product via the Products related list) then Salesforce automatically copies and syncs the OpportunityLineItem standard fields to the QuoteLineItem standard fields.
Custom fields are ignored.
This project allows you to define via custom setting which OpportunityLineItem custom fields you want copied down to the newly created QuoteLineItem custom fields.
Please note that this project currently does not handle syncing. I explain why in more detail on the project’s FAQ. In short, it’s a really hard problem to get right and not risk data corruption. Users aren’t happy when you corrupt their data.
This solution, openly available on GitHub, uses a Custom Setting to let you configure which fields you want copied from the OpportunityLineItem to the QuoteLineItem. Since standard fields are already handled by Salesforce automatically then you only need to configure custom fields in the custom setting mapping.
In the below screen shots I show an example where I’ve created custom fields on both the OpportunityLineItem and QuoteLineItem named Warranty__c. I use the custom setting to indicate that I want to map the two fields together (conceptually like Lead Field Mapping from Lead to Account).
On my opportunity, I added two products and populated the Warranty custom field.
I then created a new quote. Automatically, Salesforce creates QuoteLineItems based on the OpportunityLineItems of the parent opportunity, and it copies all the standard field values. My solution takes this a step further and ensures the custom fields are populated too. Without my trigger then the QuoteLineItem.Warranty__c field would still be blank.
Take a look at this unmanaged package code. It does support syncing of custom line item fields:
https://appexchange.salesforce.com/listingDetail?listingId=a0N30000003Iop5EAC
LikeLiked by 1 person
Hi Tamar,
Thanks for the feedback. I have looked at that app and when I reviewed the code I noticed it was syncing by trying to match opportunity line items to quote line items by concatenating various field values together trying to create a “unique” cross reference key.
However, that has the risk (read the app reviews) of corrupting data because if you add the same product, quantity, price, etc to the opportunity then the code can’t determine a unique key and thus matches against multiple records. The code tries to disambiguate (per app description) based on line item sort order but to me that is too risky.
I know syncing is an important feature but without a well defined unique cross reference key the risk of data corruption to me is too high.
Thanks,
Doug
LikeLike
Also read the reviews about data corruption at end of this forum: https://developer.salesforce.com/forums?id=906F00000009BebIAE
That is the “website” link provided on the AppExchange listing.
LikeLike
Hi Doug,
Yes, this app is not perfect and I have had it error on me when I’ve had processes running on both quote and oppty line items but most of the time it works fine. I have never added the same product twice in the same opportunity so I haven’t experienced data corruption. It’s too bad SF doesn’t give any love to the quote object lately. This should have been an out of the box functionality.
LikeLiked by 1 person
I agree. Since your comment, I’ve been mulling around making another version that supports sycning of OLI to QLI based on similar methodology of a pseudo cross-reference key, but to raise error if there’s an ambiguous setup. Like a safety net.
I’m thinking of maybe a checkbox on the Quote that toggles whether the line item syncing should be on or off. Disable if the user really needs an ambiguous setup, otherwise can leave it on so long as they have no ambiguity.
I also think the Labs App does more around syncing Quote and Opportunity fields, but that’s overkill for my purposes at the moment.
Thanks
LikeLike
I would really like to try it out, however when I go to deploy and try to login to salesforce I get this error:
Oops, something went wrong…
Authentication Failed: OAuth login invalid or expired access token
Be sure your Salesforce organization does not have IP restrictions. Logout and try with another user or organization.
Logout
We have no IP restrictions
LikeLiked by 1 person
Hi Darren,
Glad you’re wanting to try out this solution =)
I believe you’re referring to the Deploy from GitHub link on the project’s README page. That uses a web-based deployment tool developed by Andy Fawcett. If you continue to have issues with it you may want to reach out to him.
When you click that deploy link, make sure that you’re choosing the “Deploy To” that matches the login you use (e.g. Production vs. Sandbox). Another item to consider is whether you are a System Administrator profile or not, as well as whether your org has option enabled that an admin must first whitelist / approve any connected app logins.
Another thing to try is use your browser’s “incognito” mode or simply try another browser and login that way.
If still have issues, you can also simply download the metadata from GitHub to your computer as a .ZIP file then use Workbench to deploy the config.
LikeLike
Hi Doug,
I tried this solution but when creating a new quote after adding products, I get the following error:
Apex script unhandled trigger exception by user/organization: Source organization: (null)
QuoteLineItemTrigger: execution of BeforeUpdate
caused by: System.SObjectException: Invalid field Primary_Users__c for QuoteLineItem
Class.QuoteLineItemTriggerHandler.copyOpportunityLineItemFieldsToQuoteLineItemFields: line 149, column 1
Class.QuoteLineItemTriggerHandler.handleBeforeUpdate: line 60, column 1
Trigger.QuoteLineItemTrigger: line 14, column 1
LikeLiked by 1 person
Hi Sana,
Thanks for checking out my solution!
Per that error message, “Invalid field Primary_Users__c for QuoteLineItem”, the copying is failing because the field Primary_Users__c does not exist on QuoteLineItem object.
When configuring your field mappings in the custom setting “Quote Line Item Field Mapping” make sure that the chosen fields exist on the object they represent (OpportunityLineItem or QuoteLineItem). If they do exist then check your field level security. If you still have issues please open an issue on the GitHub project with screen shots of your custom setting config and fields of your objects.
Thanks!
LikeLike
Hi Doug,
I’m one of your fans.
We are now using standard quotes and built custom fields to manage subscriptions in Opps/Quotes.
We have deployed and tested your code in Sandbox and then in Prod.
As a matter of fact, we have added processes and flows, but also SF Labs managed package “custom quote sync”. We end up now with conflicts as on quote creation from an opportunity that has products, the resulting quote has quote line items that are duplicated up to 10 times.
I don’t think your code might be at stake (as you don’t create line items), but to start afresh, we’d like to uninstall all packages and redeploy them.
So my question is: how can we uninstall your code from our production environment? I don’t see any “installed package” and I don’t use force.com IDE.
Sorry if my question seems to be coming from a junior…
And again, thank you for all you do!
LikeLiked by 1 person
Hi Guillaume!
Makes me very happy to hear that you appreciate my work =)
Regarding the duplication, I would guess it’s a conflict between my app and the salesforce labs app “custom quote sync”.
Try only having one of those two apps actually installed/enabled since they both are triggers to do the same thing, but my app uses (in my opinion) an approach that is less likely to cause data corruption in edge scenarios.
LikeLike
Hello Doug,
As a matter of fact, Salesforce had a bug that generated multiple times the line items when creating a quote from an opportunity with products.
They patched it, and now everything seems to be running fine.
We now use your code for copying custom fields upon creation and Salesforce labs unmanaged app for keeping them in sync. And… it just works!
So: thanks, you saved the day with your code!
LikeLiked by 1 person
Thanks for the follow up and compliment Guillaume! Happy you got it all sorted out 🙂
LikeLike
Hi,
Does this work with Long text area ?
I created one description__c (Type : Long text area) field on Opportunity line item and the same field on quote and the data are not syncing when i create a quote.
Thanks for your help !
LikeLiked by 1 person
Hi Tim,
Any field data type should be supported, the code does not discriminate it will query and copy over whatever field API names are setup in the Quote Line Item Field Mapping custom setting.
Things to check are if the included Workflow Rule and Trigger are active in the org.
If it continues to not work, please open a GitHub issue with screen shots of your configuration and setup to help troubleshoot.
Thanks,
Doug
LikeLike
Does this solution work in Lightning Experience? I know the Salesforce Labs package does not.
LikeLiked by 1 person
Hi Firas,
I can’t imagine why this solution wouldn’t work in Lightning Experience. With that said, I can’t recall if I ever tested it in Lightning Experience.
Try it out and let us know 😉
Thanks
LikeLike
Hi, As a matter of fact we use both Salesforce Labs package and Doug’s package live in Lightning experience. Quotes created from opps are created with custom fields retrieved, and synced quote are synced with their custom fields.
LikeLiked by 1 person
Hi Doug…. Sorry for the really dumb questions but how do I get to the Quote Line Field Mapping? I don’t see it in the Custom Settings. Thanks for any help you can provide!
LikeLike
once you go custom setting there you can find manage button.
LikeLike
Hi Doug Ayers,
I appriciate your work. This stuff really good when i create Opportunity product with QuoteLine Item. But i am facing problem when i update field, the changes are not reflected.
Appriciated any help.
LikeLike
Hey Doug,
This is great and I loved it in my sandbox but I’m a little bit of a novice when it comes to what I need to do to get this to work in my prod org. Any info on how I can do this?
LikeLike