This seems so simple, but it was late and I might have been over-complicating things!
I'm currently using the woocommerce_thankyou hook in the WP functions file to compile some data and send it to a third party API. So far, so easy, using standard $order and $order_meta values. But I need to get the total number of items in an order, and I can't see where to get it.
So if someone orders 2 green widgets and 3 blue widgets, I need to get 5 from somewhere.
Am I missing something obvious? :-)
Counting order items can be 2 different things:
Total items count:
// Get an instance of the WC_Order Object
$order = wc_get_order( $order_id );
$items_count = count( $order->get_items() );
// Testing output
echo $items_count;
The total items quantity count:
// Get an instance of the WC_Order Object
$order = wc_get_order( $order_id );
$total_quantity = 0; // Initializing
// Loop through order items
foreach ( $order->get_items() as $item ) {
$total_quantity += $item->get_quantity();
}
// Testing output
echo $total_quantity;
Or you can use the WC_Order get_item_count() method that do the same (see its source code):
// Get an instance of the WC_Order Object
$order = wc_get_order( $order_id );
$total_quantity = $order->get_item_count();
Use this to get total items in a order -
$order = wc_get_order( $order_id );
echo $order->get_item_count(); // Will display the total numbers
Related
everybody !
I'm looking for a way to no decrement when an order is completed.
Exemple: I got 1 T-shirt with 20 quantity. When i order, i want the number to be still 20, and not 19.)
here my hook:
add_action( 'woocommerce_order_status_completed', 'action_on_order_completed' , 10, 1 );
function action_on_order_completed( $order_id )
{
// Get an instance of the order object
$order = wc_get_order( $order_id );
// Iterating though each order items
foreach ( $order->get_items() as $item_id => $item_values ) {
// Item quantity
$item_qty = $item_values['qty'];
// getting the product ID (Simple and variable products)
$product_id = $item_values['variation_id'];
if( $product_id == 0 || empty($product_id) ) $product_id = $item_values['product_id'];
// Get an instance of the product object
$product = wc_get_product( $product_id );
// Get the stock quantity of the product
$product_stock = $product->get_stock_quantity();
// Increase back the stock quantity
wc_update_product_stock( $product, $item_qty, 'increase' );
}
}
But when the order is completed, the quantity still decrease. Any idea ?
That is because your hooked function is triggered after stock quantity is decreased.
You are trying to get previous stock quantity with
$product_stock = $product->get_stock_quantity();
But in that case this method returns already decreased value.
So, try this:
wc_update_product_stock( $product, $product_stock + $item_qty, 'increase' );
I am developing stock status log feature to collect data of all products stock changes. I am using "woocommerce_product_set_stock" hook to write changes to custom database table. One big issue is that I cannot find out how to get related order to stock change when someone has placed a new order. When stock change is based on order cancel/refund I can get the order id from $_SERVER info but when placed a new order via checkout, there's nothing related to order id.
Customer requires order id information on stock change log so any hints, please?
When order cancelled or pending WooCommerce called this wc_reduce_stock_levels and wc_increase_stock_levels function to handle stock quantity.
You can use woocommerce_reduce_order_stock and woocommerce_restore_order_stock to write changes to your custom database table
function update_in_custom_table( $order ){
$order_id = $order->get_id();
$order = wc_get_order( $order_id );
// We need an order, and a store with stock management to continue.
if ( ! $order || 'yes' !== get_option( 'woocommerce_manage_stock' ) ) {
return;
}
// Loop over all items.
foreach ( $order->get_items() as $item ) {
if ( ! $item->is_type( 'line_item' ) ) {
continue;
}
$product = $item->get_product();
if ( ! $product || ! $product->managing_stock() ) {
continue;
}
$stock_quantity = $product->get_stock_quantity();
}
}
add_action( 'woocommerce_reduce_order_stock', 'update_in_custom_table', 10, 1 );
add_action( 'woocommerce_restore_order_stock', 'update_in_custom_table', 10, 1 );
I have created a function that is supposed to update certain meta fields once an order has been placed with Woocommerce.
Although I can confirm that the function is fired, I cannot seem to be able to load the order by the ID. Here is my code so far:
add_action('woocommerce_new_order', 'wc_update_bib_options');
function wc_update_bib_options($order_id) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ($items as $item) {
// Some stuff...
}
}
I can confirm that $order_id is passed and is an integer. Also, if I enter an ID of another (previous) order, the code works just fine...
I also tried using
$order = new WC_Order( $order_id );
But I get the same results...
Can anyone help me out?
I'm trying to get Item or Product Attribute in WooCoomerce Order.
How can I get it?
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$pid = $item['product_id'];
$patt = $pid->get_attribute( 'pa_myattrname' );
echo $patt;
}
Later, I want to insert autoresponder link on attribute, so that after user complete payment, they will automatically subscribed into my autoresponder.
Thank you
I know that it is old question, but that answer may help someone who is looking for nicer option.
There is much simpler way to get product attributes from order. You just need to go into products (items) and then load meta data
// at first get order object
$order = wc_get_order($orderId);
// iterate through order items/products
foreach ($order->get_items() as $item) {
// load meta data - product attributes
foreach ($item->get_meta_data() as $metaData) {
$attribute = $metaData->get_data();
// attribute value
$value = $attribute['value'];
// attribute slug
$slug = $attribute['key'];
}
}
$item['product_id']; will return the integer product_id, you cannot call get_attribute method on it. Using the integer product_id you need to create a Product object and then call the method
$pid = $item['product_id']; // returns the product id
$p = new WC_Product( $pid ); // create an object of WC_Product class
$patt = $p->get_attribute( 'pa_myattrname' ); // call get_attribute method
echo $patt;
For a specific woocommerce project, I need to set every new order on hold.
It needs to go through that before processing payment.
Do you guys know a hook to do that? I tried many different things, that didn't work.
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
global $woocommerce;
if ( !$order_id )
return;
$order = new WC_Order( $order_id );
$order->update_status( 'on-hold' );
}
This is the standard way of doing it. Not sure if it still works with 2.2, but you didn't specify your WooCommerce version.