Hello All,

I'm facing a very tricky issue that is related to other issues I could identify but the difference with my issue is such that I judged it relevant to put it in a separate one. Here is the issue I have:

I created a rule that is triggered on the "Before saving a commerce order" this rule is being usually triggered when created a new order and when updating an existing order.

The main action of this rule is to dynamically create a new line item (updating an existing line item) of type "coupon" (from the Commerce coupon module). This action is a custom action that is written in php, receives a couple of arguments (among them the order object) and perform the following:
1. Create/load the coupon line item
2. Add the right price components into the line item (here I erase the previous components and put new ones with updated price)
3. Save the line item
4. Add the line item to the commerce_line_items field (in case it is a newly created line item)

The wrong behavior I encounter is spotted on the order view page, when an update operation is made on the Line Item, by the following:
1. The order total which contains the coupon line item doesn't show the correct price (it always show the "previous" price, i'll explain that later)
2. The order total is computed according to the "previous" line item price

By previous what I actually mean is that the amount alway correspond to the previous save that has been made, that could be illustrated as follows:
A. Create new Line item with amount [Line item value: 100 USD | Line item showed on order view page: 100 USD] -> here no problems
B. Go on edit order page, modify the line item value, save order [Line item value: 150 USD | Line item showed on order view page: 100 USD] -> I know the value is correct by going on the database and checking the value of the total_price attached to the line item (even the components are correct)
C. On the edit order page modify again the Line item value, save order [Line item value: 120 USD | Line item showed on order view page: 150 USD]
and so on..

I concluded that the Order is being saved before the line item's new value is being submitted to the database (or some cache ?) but I can't find a way to force the new value to be taken, I tried to use the function commerce_line_item_rebase_unit_price($line_item) in conjuction with the "cart: true" property on the status the order is on, but this threw a "Nesting level too deep" error on the commerce_cart_order_refresh(). This is not the only problem as the problem persist on the whole order page (view and edit) the only way to solve the problem is either to remove the cart: true property or to erase the Line item (with its reference) in the database...

I would like to find a solution that doesn't require to set the cart: true property as I noticed this has a huge hint on performances (each time an order is viewed it is refreshed and thus saved again..., even when the order is being loaded from a view).



JulienF’s picture

For interested people, the quick fix is to
1. pass the order as a parameter to the rule
2. Wrap the order in the ordercontroller
3. Save the order after done editing it (inside the rule action) -> with my current understanding this means the order gets saved multiple times...

You'll need to make sure you keep your line item references consistent in your order object before saving it.

I think it's not an optimized solution and I can only think of passing the parameter as a reference to the rule (if possible) so the editions get saved at the end of the rule call (if this doesn't solve the problem i guess this means the ordering of calls is the problem)

If anyone did it already that would be great to share as I don't have time for this issue anymore.


rszrama’s picture

I'm having a hard time telling from the description if the issue here isn't just that you're trying to manipulate line item prices in an incorrect event. All price calculations should typically happen during the event "Calculate the sell price of a product", so are any of the line items affect product line items? Or are they all just your custom line item type?

JulienF’s picture

I'm not altering the prices of product line items in my custom action, only the amount of my custom line item type.

The reason I do that is to dynamically set the amount of a price reduction on an order that is being edited by an administrator. This makes sense here because it is a B2B ordering management platform, and thus the supplyer might be willing to perform a specific discount for each order.

(By the way, I've also noticed that putting a dpm (from the devel module) into a rule with "Before saving order" event was messing big time with the Product Line Item components by inputting some random amounts that go over the size limit of the field order_total in the database and thus breaks the website (the rule is fetching prices from the product line items but doesn't alter them). Where shall I put this issue ? into the devel module ? the rule module ? the commerce module ?)

Apologies if my first description isn't clear enough, I would be glad to answer any question.

rszrama’s picture

Category:bug» support
Status:Active» Closed (cannot reproduce)

Sorry I didn't get back to this for so long, but I'm still just not really sure what the issue is that you're describing. It could just be a lack of precision in your terms - when you say "line item amount" I think you mean line item unit price, but then I'm not really sure how your custom code is working with that number. I don't know if you're properly setting price components, and I can't tell if when you talk about the line item being displayed you really mean the order total.

Without greater precision, some code examples, or Rules that illustrate the problem, there isn't going to be a reproducible bug for me to tackle. Right now I think it's best to just close this and instead link to the feature request to better enable the recalculation of prices on non-cart orders here: #1918978: Allow administrators to trigger price calculation on an order

rszrama’s picture

Issue summary:View changes

Completed the message