Woocommerce action `woocommerce_order_status_completed` not executing - wordpress

We have a problem as I am not a woocommerce developer. The client wants to make a product out of stock once the order is completed (and payment received).
I added an action in functions.php
add_action( 'woocommerce_order_status_completed', 'set_product_out_of_stock', 10, 1 );
function set_product_out_of_stock( $order_id ) {
error_log( "This is a test: set product out of stock $order_id ^^", 0 );
//if ( 'completed' == $order_status) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$status = 'outofstock';
update_post_meta($item['item_id'], '_stock', 0);
update_post_meta( $item['item_id'], '_stock_status', wc_clean( $status ) );
wp_set_post_terms($item['item_id'], 'outofstock', 'product_visibility', true );
}
// }
}
The problem is that this action is not even triggered, The error_log doesn't show in the logs.. what may be the issue?
The website uses woocommerce v 4.7 .
Thank you !

Related

No result when using the "woocommerce_new_order" hook when order has status "processing"

I need Telegram notifications to be sent when the order status is "Processing", so I have this code:
add_action( 'woocommerce_new_order', 'new_order_send_tg', 1, 1 );
function new_order_send_tg( $order_id ) {
$order = wc_get_order( $order_id );
$msg .= '✅ Order № '.$order_id . ' *success*';
$userId = '-xxxxxxxxxxxxxx'; // ID Chat
$token = 'xxxxxxxxxxxxxxxxxxxxxxxx'; // Token bot
if( 'processing' == $order->get_status() ) {
file_get_contents('https://api.telegram.org/bot'. $token .'/sendMessage?chat_id='. $userId .'&text=' . urlencode($msg) . '&parse_mode=markdown'); // Send
} else {
//
}
}
Without the if( 'processing' == $order->get_status() ) condition, everything works as expected. But with the if condition added this doesn't seem to be the case. Any advice?
It looks like the woocommerce_new_order hook is executed before the order status is changed to processing
function action_woocommerce_new_order( $order_id, $order = null ) {
// Get order
$order = is_a( $order, 'WC_Order' ) ? $order : wc_get_order( $order_id );
$status = $order->get_status();
// Result: status = pending
}
add_action( 'woocommerce_new_order', 'action_woocommerce_new_order', 10, 2 );
So you can use the woocommerce_order_status_' . $status_transition['to'] composite action hook instead, where you will replace $status_transition[to] by processing
function action_woocommerce_order_status_processing( $order_id, $order ) {
// Do your thing
}
add_action( 'woocommerce_order_status_processing', 'action_woocommerce_order_status_processing', 10, 2 );

Cancel all user orders on subscription cancelled/expired

I want to develop a setup/code in which all the orders made by the user gets cancelled when the his subscription gets cancelled or expired. I am using Wordpress, Woocommerce and Woocommerce Subscriptions plugin.
I am trying to do by using something like this:
function my_cancelled_subscription( $user_id, $subscription_key ) {
//what code should I use here????
}
add_action( 'woocommerce_subscription_status_cancelled', 'my_cancelled_subscription', 10, 2 );
Please help mee.....
I figured it out..........
function my_cancelled_subscription( $subscription ) {
$order_id = $subscription->get_parent_id();
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
$order->update_status( 'cancelled' );
$args = array(
'customer_id' => $user_id,
'status' => 'wc-completed',
);
$arrorders = wc_get_orders( $args );
foreach ($arrorders as $ord) {
$ord->update_status( 'cancelled' );
}
}
add_action( 'woocommerce_subscription_status_cancelled', 'my_cancelled_subscription' );

Auto update product custom field based on WooCommerce product stock

I have an ACF field "DeliverySpeed" attached to Products with the values 'Fast' and 'Slow'
I would like to update this field to change to value 'Slow' every time the product stock is zero or less (product on backorder)
I am still learning PHP so far this is what I got to but I am sure different things are missing, I just don't know in which direction to go:
based on acf update field documentation
function automatically_change_delivery( ) {
global $product;
$fieldkey = "DeliverySpeed";
$valueslow = "Slow";
if($product->get_stock_quantity()<0) { update_field( $field_key, $valueslow, $post_id );
} }
Thank you in advance for the attention and advice.
The following code will update automatically your product custom field once order has reduced product stock levels. So when product has stock the custom field value will be 'Fast' otherwise 'Slow'.
The code:
add_action( 'woocommerce_payment_complete', 'update_product_custom_field_after_reduced_stock_levels', 20, 2 );
add_action( 'woocommerce_order_status_completed', 'update_product_custom_field_after_reduced_stock_levels', 20, 2 );
add_action( 'woocommerce_order_status_processing', 'update_product_custom_field_after_reduced_stock_levels', 20, 2 );
add_action( 'woocommerce_order_status_on-hold', 'update_product_custom_field_after_reduced_stock_levels', 20, 2 );
function update_product_custom_field_( $order_id, $order = '' ) {
// Continue only when order has reduced product stock levels
if ( wc_string_to_bool( get_post_meta( $order_id, '_order_stock_reduced', true ) ) )
return $order_id; // Exit
if( ! $order || ! is_a( $order, 'WC_Order') ) {
$order = wc_get_order( $order_id ); // Get the WC_Order object if it's empty
}
$field_key = 'DeliverySpeed';
// Loop through order items
foreach ( $order->get_items() as $item ) {
$product = $cart_item['data'];
$product_id = $product->get_id();
$stock_qty = $product->get_stock_quantity();
$field_value = get_field( $field_key, $product_id ); // Get ACF field value
if ( $stock_qty <= 0 && $field_value === 'Fast' ) {
update_field( $field_key, 'Slow', $product_id );
}
elseif ( $stock_qty > 0 && $field_value === 'Slow' ) {
update_field( $field_key, 'Fast', $product_id );
}
}
}
Code goes in functions.php file of the active child theme (or active theme). It should works.

How to change user rol after buying in Woocommerce

thank you for any of you guys wanted to help me, I just want to know how to change the user role in WordPress when users buy something. I'm using WooCommerce. Regards
You can use Woocommerce action hooks. check my below code.
add_action( 'woocommerce_thankyou', 'change_user_role_afte_buying' );
function change_user_role_afte_buying( $order_id ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
$products_to_check = array( '1', '2', '3' ); // your product ids for checking someting buy
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id ); // get user Object
$user->remove_role( 'customer' ); // remove old role
$user->add_role( 'new-role' ); // add new role
break; // Exit the loop
}
}
}

How to Accept Orders on Woocommerce as per location?

I have a woocommerce website hosted on domain https://www.micropediaglobal.com.
I have one requirement that my different branch managers located at different locations should see the orders as per the locators and process their orders only.
Can someone please guide here ?
The Website Development Company website does not seems to be on wordpress, however you can bifurcate or process woocommerce orders location wise as below:
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['xerox_shop_name'] ) ) {
update_post_meta( $order_id, 'xeroxshopmeta', sanitize_text_field( $_POST['xerox_shop_name'] ) );
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Xerox Center Name').':</strong> ' . get_post_meta( $order->id, 'xeroxshopmeta', true ) . '</p>';
}
//add custom field column
add_filter( 'manage_edit-shop_order_columns', 'MY_COLUMNS_FUNCTION' );
function MY_COLUMNS_FUNCTION( $columns ) {
$new_columns = ( is_array( $columns ) ) ? $columns : array();
unset( $new_columns[ 'order_actions' ] );
//edit this for your column(s)
//all of your columns will be added before the actions column
$new_columns['xeroxColumn'] = 'Xerox Center Name';
//stop editing
$new_columns[ 'order_actions' ] = $columns[ 'order_actions' ];
return $new_columns;
}
add_filter( "manage_edit-shop_order_sortable_columns", 'MY_COLUMNS_SORT_FUNCTION' );
function MY_COLUMNS_SORT_FUNCTION( $columns )
{
$custom = array(
'xeroxColumn' => 'xeroxshopmeta',
);
return wp_parse_args( $custom, $columns );
}
add_action( 'manage_shop_order_posts_custom_column', 'MY_COLUMNS_VALUES_FUNCTION', 2 );
function MY_COLUMNS_VALUES_FUNCTION( $column ) {
global $post;
$data = get_post_meta( $post->ID );
//start editing, I was saving my fields for the orders as custom post meta
//if you did the same, follow this code
if ( $column == 'xeroxColumn' ) {
echo get_post_meta( $post->ID, 'xeroxshopmeta', true );
}
}

Resources