I'm seeing a weird change in an OpportunityLineItem's TotalPrice
when changes are made to the Quantity
field.
These records have an additional custom field that holds a fixed rate price that is entered by the user. When the OpportunityLineItem is edited via a Visualforce page the Quantity
is updated via an <apex:inputText>
and the controller sets the TotalPrice
to the fixed rate price that the user entered.
After saving the OLI for an existing record, the TotalPrice
is changing to be the Quantity
* UnitPrice
, even though the code that just did the update explicitly set the Quantity
and TotalPrice
fields. I'd expect the UnitPrice
to change instead as it wasn't explicitly set in code.
I can replicate this with anonymous Apex:
integer newQuantity = 17;
OpportunityLineItem oli = [Select Id, UnitPrice, TotalPrice, Quantity from OpportunityLineItem where Id = '00k4000000u8Uvm'];
decimal tp = oli.TotalPrice;
System.assertNotEquals(newQuantity, oli.Quantity, 'Expected to be changing just the Quantity');
System.debug('Before TotalPrice: ' + oli.TotalPrice +
'\n Quantity: ' + oli.Quantity);
oli.Quantity = newQuantity;
// Keep the TotalPrice unchanged
oli.TotalPrice = tp;
update oli;
OpportunityLineItem oliAfterUpdate = [Select Id, UnitPrice, TotalPrice, Quantity from OpportunityLineItem where Id = '00k4000000u8Uvm'];
System.debug('After TotalPrice: ' + oliAfterUpdate.TotalPrice +
'\n Quantity: ' + oliAfterUpdate.Quantity +
'\n UnitPrice:' + oliAfterUpdate.UnitPrice);
System.assertEquals(tp, oliAfterUpdate.TotalPrice);
The assertion is failing above. The TotalPrice
is changing rather than the UnitPrice
.
There are no revenue schedule record for the OpportunityLineItem.
Note that a subsequent update to the Quantity with the original TotalPrice
will update the UnitPrice
as expected. It's only if the TotalPrice
is the same as the currently stored value that the UnitPrice
gets fixed.
From the Docs:
Totalprice If you do not specify UnitPrice, this field is required. If you specify Discount and Quantity, this field or UnitPrice is required. When updating these records, you can change either this value or the UnitPrice, but not both at the same time.
This field is nillable, but you can’t set both TotalPrice and UnitPrice to null in the same update request.