The function commerce_cart_order_product_line_item_delete()
provides a skip_save
argument which would allow you to not save the order when invoking that function:
function commerce_cart_order_product_line_item_delete($order, $line_item_id, $skip_save = FALSE) {
...
// Delete the actual line item.
commerce_line_item_delete($line_item->line_item_id);
if (!$skip_save) {
commerce_order_save($order);
}
But when invoking commerce_line_item_delete()
the order is saved anyway by
commerce_line_item_delete()
>> commerce_line_item_delete_multiple()
>> CommerceLineItemEntityController->delete( )
>> commerce_line_item_delete_references()
>> entity_save()
So this causes an infinite loop when you have logic in a hook_commerce_order_presave() that removes a line item.
So unless I'm using the wrong hook or function to remove a line item I suppose this is a bug.
Use case:
There are administrative costs that need to be added when the order is below a certain amount. So I check on commerce_order_presave() what the value of the cart is and I either add/remove/leave the admin-costs product.
Comment | File | Size | Author |
---|---|---|---|
#11 | 2316709-skip_save-11.patch | 2.87 KB | jcisio |
| |||
#10 | interdiff-8-9.txt | 838 bytes | czigor |
#10 | commerce-2316709-9-skip-save.patch | 8.25 KB | czigor |
|
Comments
Comment #1
Jax CreditAttribution: Jax commentedcommerce_shipping_delete_shipping_line_items()
has its own way of deleting line items. Not sure what is best.Comment #2
Jax CreditAttribution: Jax commentedAnd that also triggers an order save. As far as I understand it's not possible to remove a line item from an order and delaying the order save since it always passes through commerce_line_item_delete_references() which saves the order.
If that's the case please close this ticket. I will need to find another place to do the calculation. Any suggestions for where are welcome.
Comment #3
rszrama CreditAttribution: rszrama commentedTagging for http://contribkanban.com/#/board/commerce/7.x-1.x.
Comment #4
mglamanFix formatting
Comment #5
mglamanSounds like $skip_save is unable to provide functionality due how commerce line item's are saved. Perhaps we should just remove it to reduce confusion?
Comment #6
czigor CreditAttribution: czigor commentedJust bumped into this when I needed to remove line items on order change. Looking at the line item entity controller it seems to be impossible to remove line items without saving the order.
Since it seems to be easy to pass down $skip_save to the controller, let's pass down $skip_save to the controller.
Our use case is removing products, that are for sale only in one currency, from the cart when the order currency changes.
Comment #7
czigor CreditAttribution: czigor commentedThis is more complicated than this. We need to pass down the parent entity as well, otherwise we throw out the baby with the bath water.
Comment #8
czigor CreditAttribution: czigor commentedComment #10
czigor CreditAttribution: czigor commented5.3. does not support the
syntax.
Comment #11
jcisio CreditAttribution: jcisio at Axess Open Web Services commentedNew patch, only pass $skip_save.
Comment #12
czigor CreditAttribution: czigor at Centarro for FREITAG lab. AG commentedThe changes in #11 make sense and also work for us.
Comment #13
czigor CreditAttribution: czigor at Centarro for FREITAG lab. AG commentedComment #15
rszrama CreditAttribution: rszrama at Centarro commentedGreat, thanks for the patches and reviews! Committing #11 with a little extra documentation in the controller to ensure callers know they are responsible for saving the order if they opt to skip the save in the controller's delete method.
Comment #17
ezeedub CreditAttribution: ezeedub commentedLooks like #11 removed the actual fix to commerce_cart_order_product_line_item_delete(). Since this has already been released, I created a new issue #3006593 to add that back.