While performing regression tests on a Summer'21 sandbox, I noticed that custom fields were not filled in newly created QuoteLineItems.
For many years, I have used the trick as described here, and upon inspection, I found out that OpportunityLineItemId is no longer present in the JSON representation of a new QuoteLineItem.
After some experimenting, I executed this little piece of code in the Summer'21 sandbox:
QuoteLineItem qli1 = new QuoteLineItem(QuoteId = '0Q03M0000004XBUSA2', Quantity = 1, HoeveelheidBayreuth__c = 1, Line_number__c = 1, UnitPrice = 99.00, PricebookEntryId = '01u58000005wszNAAQ', OpportunityLineItemId = '00k3M000003TIOKQA4'); insert qli1; System.debug('qli1.Id = ' + qli1.Id); QuoteLineItem qli2 = [SELECT Id, PricebookEntryId, OpportunityLineItemId, OpportunityLineItem.Id FROM QuoteLineItem WHERE Id = :qli1.Id]; System.debug('qli2.Id = ' + qli2.Id); System.debug('qli2.PricebookEntryId = ' + qli2.PricebookEntryId); System.debug('qli2.OpportunityLineItemId = ' + qli2.OpportunityLineItemId); System.debug('qli2.OpportunityLineItem.Id = ' + qli2.OpportunityLineItem.Id);
And, lo and behold, the last two lines give null results. In a Spring'21 sandbox, both last two lines give the Id of the corresponding OpportunityLineItem (of course I used the appropriate hard-coded ids for the sandboxes).
You can also see this behaviour without using Apex: create an Opportunity, an OpportunityLineItem, and a Quote, all via the common user interface. Then inspect the created QuoteLineItem (OK, you have to use something like a SOQL query in Workbench for that). And even though OpportunityLineItemId is one of the QuoteLineItem's fields, it is not filled.
So, for some reason Salesforce has disabled the link between OpportunityLineItems and QuoteLineItems.
Update: sfdcfox's remark got me thinking: previously, the link between OpportunityLineItems and QuoteLineItems was always filled, even when opportunity/quote syncing was disabled. Which could be considered a bit strange. But now with Summer'21, the link is not available anymore when opportunity/quote syncing is disabled. Which makes sense, but it breaks the code that copied custom fields. I do not like to enable opportunity/quote syncing, it has too many disadvantages.
So, what other way is there to have Salesforce copy custom fields from OpportunityLineItems to QuoteLineItems when creating a Quote from an Opportunity?