I create the order with some line items in my module, and need to add shipping service to it. But I can't find any example how to do this, so I try with my hands.
I use function

commerce_shipping_service_rate_order('shipping_machine_name1', $order);

This function creates $order->shipping_rates array with 'shipping_machine_name1' item and correct commerce_unit_price and other fields.
After this I do the commerce_order_save($order);
Order is correctly saved, but I didn't see the shipping service in line items. What I do wrong?
Maybe I need to do additional steps for correctly attach shipping to order?

Comments

googletorp’s picture

Status: Active » Fixed

If you don't mind to get your hands dirty, see

commerce_shipping_line_item_add_form

and

commerce_shipping_line_item_add_form_submit

That will show you how to create a shipping line item, then all you need to do after it has been saved is to add it to the order.

murz’s picture

I look at this functions, but don't understand what I must do. Main function, as I understand, is: commerce_shipping_line_item_populate($line_item, $service, $unit_price);
But where is place when line_item is attached to order, I don't understand.
Maybe you can write the simple example?
I have an $order object and know shipping item machine name $shipping_service. I want to add this shipping service as line item into order. Shipping service is flat_rate, so it have static price. Can you write code example that do this?

Status: Fixed » Closed (fixed)

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

Tapendra Singh’s picture

Steps:
1) Create a service by using Flat Rate Module.
2) By using this code whichever shipping service is applcable will come with order object.
3) User service machine name and then call yourfunction_name($order, $service_name = NULL);



function yourfunction_name($order, $service_name = NULL){
  if (isset($service_name) && !isset($order->shipping_rates[$service_name])) {  
    // Make the chosen service available to the order. 
  commerce_shipping_service_rate_order($service_name, $order);
  }
  elseif (!isset($service_name)) {
    if (empty($order->shipping_rates)) {
      // No available rate.
      return;
    }
    $service_name = key($order->shipping_rates);
  }


  // Delete any existing shipping line items from the order.
  commerce_shipping_delete_shipping_line_items($order, TRUE);

  // Extract the unit price from the calculated rate.
  $rate_line_item = $order->shipping_rates[$service_name];
  $rate_line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $rate_line_item);
  $unit_price = $rate_line_item_wrapper->commerce_unit_price->value();

  // Create a new shipping line item with the calculated rate from the form.
  $line_item = commerce_shipping_line_item_new($service_name, $unit_price, $order->order_id, $rate_line_item->data, $rate_line_item->type);

  // Save and add the line item to the order.
  $new_line_item = commerce_shipping_add_shipping_line_item($line_item, $order, TRUE);
  commerce_order_save($order);
}
hiramanpatil’s picture

Issue summary: View changes

@TapendraSingh

I am using this function and called it in hook_order_presave() but the page show error. This gives below error message in error logs.

DatabaseTransactionOutOfOrderException: in DatabaseConnection->rollback() (line 1084 of /var/www/html/drupal-project/includes/database/database.inc).

Thanks,

finex’s picture

Same problem here: the presave() is inside a db transition, so it can't be used to change data on the order lines. We have to call the code before or after the presave().

EDIT: solved using hook_commerce_cart_order_refresh().