woocommerce get shipping cost from zone id - wordpress

I am working in woocommerce add order from API. I already added order by using wc_create_order() function. In that, I have added shipping address, billing address, and product details as well. But the problem is I want to add shpping cost as per shipping zone.
Here is screenshot :
However I found class with function called : WC_Shipping_Zones::get_zones().
But it return unarranged (unmanaged) array.
I have state code and then I want to get shipping cost from state code.
However, I have found zone_id.
I have already tried to use WC_Shipping_Zones::get_zone_by('zone_id',$zone_id),WC_Shipping_Zones::get_zone($zone_id);
But none of functions return cost anyhow.

Here is the code to get the zone cost. I hope it helps.
global $post, $woocommerce;
$delivery_zones = WC_Shipping_Zones::get_zones();
foreach ((array) $delivery_zones as $key => $the_zone ) {
echo $the_zone['zone_name'];
echo "<br/>";
foreach ($the_zone['shipping_methods'] as $value) {
echo $value->cost;
}
echo "<br/>";
}

Related

WooCommerce update a product when opening single product view

I have to update my product with data that comes from an API query. I would like to update the products data when visiting the single products view. I'm new to WordPress and WooCommerce, but I think this can be done through hooks?
I've tried looking for hooks but haven't had any luck yet
You could do something like the example below.
This will run every time the product is viewed. Of course, you have to add your own API call and adapt the function to your data structure.
add_action('wp', 'update_product_data');
function update_product_data(){
if (class_exists('WooCommerce') && is_product()) {
$product = wc_get_product( get_the_ID() );
$product_id = $product->get_id();
// Call the external API to get the updated product data
$api_url = 'http://example.com/api/product/' . $product_id;
$response = wp_remote_get($api_url);
// Check for successful response and decode the JSON data
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) == 200) {
$data = json_decode(wp_remote_retrieve_body($response), true);
// Update the product's weight and description with the data from the API
$product->set_weight($data['weight']);
$product->set_description($data['description']);
$product->save();
}
}
}

Woocommerce Product Variation override get_stock_quantity - accessing parent object

I want to override the get_stock_quantity for a specific product to allow for a single variant to not ever run out of stock ( its virtual so no stock, but you can't switch off stock management for a single variant )
I can get my method called
function test_get_digital_stock_quantity( $value) {
echo "<br/>STOCK!<br/>";
var_dump($value);
return $value;
}
add_filter( 'woocommerce_product_variation_get_stock_quantity', 'test_get_digital_stock_quantity',10,1);
Which is great, however I only want to do it for specific variations not all. So I need to access the thing this was called on. However the function only seems to take a single parameter even though the calling code suggests its passing $this.
$value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
So the question is, how do I get the thing that the get_prop was called on in the function that I have written. I need to be able to access the SKU in order to make the decision about the stock quantity to return...
Just realised the add_filter required a 2 not a 1 for it to be passed.
add_filter( 'woocommerce_product_variation_get_stock_quantity', 'test_get_digital_stock_quantity',10,2)

Woocommerce which hook to use for order status changes

In my custom plugin I need to catch every time an order status changes from wc_on_hold to wc_completed so I tried to write down:
function so_status_completed( $order_id, $old_status, $new_status ) {
// if user is active , then get order amount and do all other personal calculations
global $wpdb;
$order = wc_get_order( $order_id );
//$payment_method = $order->get_payment_method(); //returns payment method bacs,cheque,cod etc
$user_id = $order->get_user_id();
$total = $order->get_total();
$order_data = $order->get_data();
//$order_total = $order->get_formatted_order_total();
$order_total = $order->get_total();
echo '<script>console.log("Debug Objects: Check order_total ' . $order_total. '");</script>';
}
add_action('woocommerce_order_payment_status_changed','so_status_completed',10,1);
But when I tried to change an order test from suspended to completed, I couldn't get on Chrome's Console that echo giving me the order price.....maybe using add_action isn't the right way to put a listener to that event?
Plus, since I am just here, I am using $order-get_total() which I searched on the net about his functionality but no deep docs found so I want to ask you if that method is the right one to retrieve order amount without fee applied?
Thanks! Cheers!!!
"I need to catch every time an order status changes from wc_on_hold to wc_completed"
You would need to change your hook to woocommerce_order_status_changed.
"I couldn't get on Chrome's Console that echo giving me the order price"
You can't use javascript and console.log in this hook. You would need to either use the die function or the error_log function to log it to your debug.log file.
Using die function
add_action('woocommerce_order_status_changed', 'so_status_completed', 10, 3);
function so_status_completed($order_id, $old_status, $new_status)
{
$order = wc_get_order($order_id);
//$order_total = $order->get_formatted_order_total();
$order_total = $order->get_total();
die($order_total);
}
Using error_log function
dd_action('woocommerce_order_status_changed', 'so_status_completed', 10, 3);
function so_status_completed($order_id, $old_status, $new_status)
{
$order = wc_get_order($order_id);
//$order_total = $order->get_formatted_order_total();
$order_total = $order->get_total();
error_log(print_r('order total: ' . $order_total, true));
}
Second question
"since I am just here, I want to ask you if $order-get_total() is the right one to retrieve order amount without fee applied?"
You might want to take a look at the $order->get_subtotal() for the totals before shipping, coupons and taxes:
Please see these related answers:
https://stackoverflow.com/a/47782647/15040627
https://stackoverflow.com/a/61102779/15040627
https://stackoverflow.com/a/32634480/15040627
https://stackoverflow.com/a/44708344/15040627

Troubleshooting Woocommerce order emails customized according to shipping method

Currently my two options for shipping are regular shipping (using the Flexible Shipping plugin) and local pickup. I would like my Completed Order emails to be customized according to the shipping method used for the order (e.g. I'd like the header to say "We've shipped your order!" for regular shipping and "Your order is ready for pickup!" for local pickup).
Here's my first attempt at modifying the text through my child theme's functions.php (code based on LoicTheAztec answer in this thread). Currently, instead of inserting the desired text, it shows the default text that I entered in Woocommerce>Settings>Emails>Order Completed>Completed order>Email heading, regardless of shipping method selected.
add_action( 'woocommerce_email_header ', 'modify_header_by_shipping', 10, 2 );
function modify_header_by_shipping( $email_heading, $email ) {
// Only modify "Customer Completed Order" email notification
if( 'customer_completed_order' != $email->id ) return;
//Initialize variable
$found = false;
// Get $order object from $email
$order = $email->object;
// Iterating through Order shipping methods
foreach($order->get_shipping_methods() as $value){
$rate_id = $value->get_method_id(); // Get the shipping rate ID
if ( 'shipping_method_0_local_pickup5' == $rate_id )
$found = true;
}
if ($found)
echo '<p>'.__("Your order is ready for pickup!","woocommerce").'</p>';
else
echo '<p>'.__("We've shipped your order!","woocommerce").'</p>';
}
Here's my ordering page: https://carrickseeds.ca/checkout/

Woocommerce get Shipping Zone

Does anyone know how to get the shipping zone from woocommerce?
I think this comes from the table rate shipping extension but has now been added to WC core.
I'm guessing it's similar to
WC()->customer->get_shipping_country();
Thanks!
You can easily get the shipping zones by following given code
$delivery_zones = WC_Shipping_Zones::get_zones();
foreach ((array) $delivery_zones as $key => $the_zone ) {
echo $the_zone['zone_name'];
}
It will return the zone information for each zone.

Resources