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.
The shipping rate will be calculated based on the DIM weight or the package's actual weight, whichever is larger.
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.
Go to WooCommerce -> Settings -> Shipping -> Shipping Packages and configure merge shipping packages conditions.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With