Hi great module, not sure if this should be classed as a bug or feature request, but as I managed to get a “Shipping X” price on the checkout stage while “Shipping Y” option selected, I went for a bug report.

Below is an explanation of how a user can get the wrong shipping cost on the checkout stage:

After selecting a shipping option in checkout and continuing to review order – the correct shipping line item is added

If the user goes back to the checkout and selects a different shipping option (or as in my case rules may change this option automatically if he changed the items in the cart) – you get the old shipping line item in the checkout until you continue to review order where the line item is updated.

What would be good is if the “Enable Shipping” method will clear any existing shipping line items, so checkout never shows shipping costs.

Comments

Devline’s picture

I personally added a routine to delete the shipping line-item in submit_form() handler then use a drupal_goto() to refresh the page. You could maybe have look at this #1185954: After updating to Drupal Commerce 7.x-1.0-beta4 , Commerce Shipping throws serious errors or at the code that is taking care of the delete in checkout-review.

guy_schneerson’s picture

Thanks Devline
I was trying a similar approach of clearing the line items but was missing the drupal_goto that got it working for me.
I used the form_label function in my ctools shipping plugin, feels like the wrong place for it but it is one of the first thing called by commerce_shipping_pane_checkout_form, see my code below:

  public function form_label($order = NULL) {
    if (empty($order)) {
      $order = $this->order;
    }
    
    $flag_remove_shipping = false;
    // In case this order already have shipping line items, we need to remove them.
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
    $delete_line_items = array();
    foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
      if ($line_item_wrapper->type->value() == 'shipping') {
        $order_wrapper->commerce_line_items->offsetUnset($delta);
        $flag_remove_shipping = true;
      }
    }
    $order_wrapper->save();

    if ($flag_remove_shipping) {
      $current_url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];    
      drupal_goto( $current_url);
    }
    return 'Flat rate Shipping';
  }

This fixes it for me but I still think that the commerce_shipping module should clear the line items when checking out possibly in commerce_shipping_pane_checkout_form

guy_schneerson’s picture

and this is just some test code as obviosly should be return t('Flat rate Shipping');

googletorp’s picture

When a new shipping type is selected (submitted) the old one is removed:

// In case this order already have shipping line items, we need to remove them.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$delete_line_items = array();
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
  if ($line_item_wrapper->type->value() == 'shipping') {
    $order_wrapper->commerce_line_items->offsetUnset($delta);
  }
}
$order_wrapper->save();

I'm not sure how you are able to select the shipping item keep the old.

If the shipping item was removed when the option to select the shipping item was presented, you would make it possible to bypass the shipping costs.

guy_schneerson’s picture

googletorp you are correct however the case I am talking about is as follows:
1) A user goes from checkout to review order (shipping line item added)
2) Instead of paying user goes back to the checkout (and possibly modifying the basket first).
In such a case the shipping line item that was added will show on the checkout stage and may no longer be relevant to the contents of the cart or the delivery option selected.

Once he proceeds to review order the shipping gets updated so the placed order is correct. It’s the intermediary stage of visiting the checkout and having shipping costs that is confusing for the user.

If this is still not clear I can attach some screen shots illustrating this issue.

guy_schneerson’s picture

StatusFileSize
new91.07 KB

screen shots illustrating issue

googletorp’s picture

It's up to site builders to decide how to handle this case, by standard I don't think the shipping module should delete anything. You should be able to handle this with rules alone.

googletorp’s picture

Status: Active » Postponed

Regarding SS in #6. You have based this upon the fact that you have your shipping selection at checkout. You could also have the shipping selection at the review step or some other step. I don't believe it's the commerce_shipping module's job to handle such cases. But maybe the module should create an action to make it easier to delete shipping items via rules.

I'll give this some thought, input is welcome.

guy_schneerson’s picture

ok thanks,
The code in #2 works for my project.
I had a quick go at using rules but couldn't find a way of clearing only shipping line items, but if its doable with rules alone would be even better, will give it another go maybe using a loop and "Execute custom PHP code" action.

googletorp’s picture

Status: Postponed » Fixed

I've added a Rules action to delete shipping line items on an order. Please test.

guy_schneerson’s picture

Thanks googletorp thats a very elegant solution.

Added it to my shipping rule, the only problem is that although shipping line items are cleared they are still showing in the “shopping cart contents”, adding a redirect back to the same page fixes that but it is not the most elegant solution, must be a better way.
Attached my temp fix

googletorp’s picture

You need to have the rule invoked before the page is rendered, instead of reloading the page.

guy_schneerson’s picture

i am using your "Select available payment methods for an order" event cant find any other events to work with would be great to have a “Beginning the checkout process” event

latulipeblanche’s picture

I've got the same problem that when a client goes to "Review" and decides to go back to add products to not pay the shipping the shipping is there in the "Checkout -> Shopping cart contents " (not in the new "Review".

@googletorp I saw "I've added a Rules action to delete shipping line items on an order."

Can you please tell me where to add the "delete-rule".

This is the rule I've got:

Data comparison:
Parameter: Data to compare: [commerce-order:commerce..., Operator: is lower than, Data value: 7000

Enable shipping method: PBCosmetics Shipping method:
Parameter: Order: [commerce-order]

So I add shipping-costs to an order when the order is less then 70€.
Do I need to create a new rule next to the actual one, for deleting shipping-costs when the order is more than 70€ ?

sebasto’s picture

I encoutered the same problem, I finally created a little rule for cleaning the cart when the user goes back to checkout/command id but it's far from ideal.

Anyway, if it can help, here is what I did :

1) Create a rule
- EVENT : Select available shipping methods for an order
- CONDITION : custom php code to avoid infinite redirect loop (check that we have a shipping line) , code almost copyed from commerce_shipping_clear_order ...
$order_wrapper = entity_metadata_wrapper('commerce_order', $commerce_order);
$line_items_to_delete = array();
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
if ($line_item_wrapper->type->value() == 'shipping') {
$line_items_to_delete[] = $line_item_wrapper->line_item_id->value();
}
}
return count( $line_items_to_delete) > 0;
- ACTIONS
Remove all shipping items from an order
Page redirect (to checkout/[commerce-order:order-id])

It works on my site, but I'm not very satifyed with that. Would be far better to clean the order before it is rendered, thus avoiding the redirect.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

guy_schneerson’s picture