Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate shipping methods/rates within an existing order in WooCommerce

I am essentially trying to replicate functionality like on the cart page where a user can add their zip code and it calculates available shipping rates, but I'm trying to do it from the back-end from within an already-created order.

I could not find a way to do it directly from WC_Order instance, so the next best thing I have is do clear cart session, add all items from within order to the cart session, and then try to calculate it.

Here's what I have so far. I'm always stuck on how to calculate the rates for the entire order.

$order_id       = isset($_POST['order_id'])?$_POST['order_id']:0;
$country        = isset($_POST['country'])?$_POST['country']:0;
$state          = isset($_POST['state'])?$_POST['state']:0;
$postcode       = isset($_POST['postcode'])?$_POST['postcode']:0;
$city           = isset($_POST['city'])?$_POST['country']:0;
$order          = wc_get_order( $order_id );
$order_items    = $order->get_items();

// Don't know if this would save country of logged in user, or only create a temporary guest user session which is what I'd need
if ( $country != '' ) {
    WC()->customer->set_billing_location( $country, $state, $postcode, $city );
    WC()->customer->set_shipping_location( $country, $state, $postcode, $city );
} else {
    WC()->customer->set_billing_address_to_base();
    WC()->customer->set_shipping_address_to_base();
}

// Remove all current items from cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
    WC()->cart->empty_cart();
}

// Add all items from the order to the cart
foreach ($order_items as $order_item) {
    WC()->cart->add_to_cart($order_item['product_id'], $order_item['qty']);
}

$totals = WC()->shipping->get_packages();

// $totals returns rates but I believe it is per each "package". It's not a cumulative rate like the cart page shows.
like image 459
zen Avatar asked Mar 13 '19 20:03

zen


People also ask

How is shipping costs calculate in WooCommerce?

The shipping rate will be calculated based on the DIM weight or the package's actual weight, whichever is larger.

How does WooCommerce automatically calculate shipping?

Go to WooCommerce > Settings > ACS Web Services. Check Enable ACS Automatic Shipping Calculation and press Save. On Weight you will be able to select Automatic Weight if you want to calculate the shipping fee based on order's total weight or select flat to set a fixed order weight.

How do I combine shipping in WooCommerce?

Go to WooCommerce -> Settings -> Shipping -> Shipping Packages and configure merge shipping packages conditions.


2 Answers

Ok so thanks to @mujuonly, I was able to figure it out.

Here's how to get all calculated shipping rates, the same way it's shown on the cart page.

// Post variables
$order_id   = isset($_POST['order_id'])?$_POST['order_id']:0;
$country    = isset($_POST['country'])?$_POST['country']:0;
$state      = isset($_POST['state'])?$_POST['state']:0;
$postcode   = isset($_POST['postcode'])?$_POST['postcode']:0;
$city       = isset($_POST['city'])?$_POST['city']:0;

// Order and order items
$order          = wc_get_order( $order_id );
$order_items    = $order->get_items();

// Reset shipping first
WC()->shipping()->reset_shipping();

// Set correct temporary location
if ( $country != '' ) {
    WC()->customer->set_billing_location( $country, $state, $postcode, $city );
    WC()->customer->set_shipping_location( $country, $state, $postcode, $city );
} else {
    WC()->customer->set_billing_address_to_base();
    WC()->customer->set_shipping_address_to_base();
}

// Remove all current items from cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
    WC()->cart->empty_cart();
}

// Add all items to cart
foreach ($order_items as $order_item) {
    WC()->cart->add_to_cart($order_item['product_id'], $order_item['qty']);
}

// Calculate shipping
$packages = WC()->cart->get_shipping_packages();
$shipping = WC()->shipping->calculate_shipping($packages);
$available_methods = WC()->shipping->get_packages();

$available_methods[0]['rates'] will have all the shipping rates that are available to that location for products inside the order.

like image 140
zen Avatar answered Nov 10 '22 19:11

zen


Try using:

// Calculate totals
WC()->cart->calculate_totals();
WC()->cart->calculate_shipping();

// Retrieve the shipping total
$shipping_total = WC()->cart->get_shipping_total();

The WC_Cart class should have all of the methods you would need to recreate any cart functionality you might need. I suggest that you should read through and familiarize yourself with the class definition here...

https://docs.woocommerce.com/wc-apidocs/class-WC_Cart.html

like image 23
BA_Webimax Avatar answered Nov 10 '22 19:11

BA_Webimax