I use WooCommerce to manually take orders via the telephone / email etc. I use the backend to record the orders manually adding the orders.
At present, when generating an order as 'pending payment' as the status the stock is automatically reduced / deducted. I do not want this to happen. Ideally I only want stock to be reduced when the order is marked as in 'processing' as then payment would of then been taken.
I understand this is how WooCommerce works back is there a way to avoid stock being reduced until a certain status has been selected?
I have tried the below code within functions.php and used the 'on-hold' status to test but the stock is still reduced.
add_filter( 'woocommerce_can_reduce_order_stock', 'wcs_do_not_reduce_onhold_stock', 10, 2 );
function wcs_do_not_reduce_onhold_stock( $reduce_stock, $order ) {
if ( $order->has_status( 'on-hold' )) {
$reduce_stock = false;
}
return $reduce_stock;
}
I wonder if it because I am adding the order as an admin? I know this is how WooCommerce works but ideally I need a method of overriding the 'pending payment' status when creating an order both within the draft and creation stage until marked as 'processing'.
Any help would be fantastic.
Try this adding to functions.php
Note: not tested.
function reduce_stock_processing($order_id) {
wc_reduce_stock_levels($order_id);
}
add_action('woocommerce_order_status_processing', 'reduce_stock_processing');
Related
I have a plugin I developed that connects a WooCommerce order to HubSpot. The issue i'm running into though is that while it works, the hook im using right now is sending order info to HubSpot before its technically complete. So this means that stuff like Failed orders get sent in as Pending, and coupon codes are ommitted.
So i'm wondering what the right hook to use is.
My goal: Everytime a WooCommerce order is created & completed and a WooCommerce order is updated, send the data to HubSpot.
What I have so far:
add_action('save_post_shop_order', 'printout', 10, 3);
function printout($post_ID, $post, $update)
{
if (!is_admin()){
return;
}
if($update){
$msg = $post_ID;
$order = get_woocommerce_order($msg);
mainplugin($msg, $order);
}
}
add_action('woocommerce_new_order', 'neworder_delegator', 10, 2);
function neworder_delegator($order_id, $order){
mainplugin($order_id, $order);
}
So I guess i'm just looking for the right hook to get me what I want.
Thanks!
Here is your answer:
Each WooCommerce Order transition has one or more dynamic hooks that trigger when the status transition happens.
They start with 'woocommerce_order_status_' and the remaining part of the action is either the new status that the order has transitioned to, or the to and from statuses involved in the format '<status_transition_from>to<status_transition_to>'
Examples
You can hook your function to
add_action( 'woocommerce_order_status_completed', 'your_order_completed_function');
To trigger your function only when the order transitioned to completed, and not when refunded, cancelled, on-hold, etc. as those would run on other actions such as
woocommerce_order_status_refunded
woocommerce_order_status_cancelled
woocommerce_order_status_on-hold
woocommerce_order_status_failed
woocommerce_order_status_processing
Edited to add link to official WooCommerce docs:
https://woocommerce.github.io/code-reference/hooks/hooks.html
I need help with a problem-related to plugin "WooCommerce Pay for Payment" which counting some extra fee in shipping. Problem is, that this plugin sets automatically "processing" status in order which causes thanking email for payment (in case of local payment) and don't send email notification about a new order, so customer is confused (I didn't send any money and I received email "thanks for your payment").
I tried this solution: Set WooCommerce order status when order is created from processing to pending
But it only changes order status back to "on-hold" but sends email thank for payment anyway.
Only one thing that I need is to send to the customer in every new order email about a new order, nothing more (I would like to change status to "processing" manually).
Thank you for help, I have no idea how to resolve because I couldn't find PHP file causing a change of status in the plugin.
EDIT: Sorry to all. This was problem of COD in woocommerce plugin. Not Pay for payment as I mentioned. Woocommerce COD automatically set "processing" status.
I found solution for this on github:here
Its the first code.
Based on the answer to this question, this code worked fine for me:
function sv_wc_cod_order_status( $status ) {
return 'on-hold';
}
add_filter( 'woocommerce_cod_process_payment_order_status', 'sv_wc_cod_order_status', 15 );
Updated: The code that you found in Github is outdated, clumsy and complicated, since there is a dedicated filter hook now. You should better try this lightweight and effective code, that will set the default order status for "Cash on delivery" payment gateway (COD) to "On Hold":
add_filter( 'woocommerce_cod_process_payment_order_status', 'change_cod_payment_order_status', 10, 2 );
function change_cod_payment_order_status( $order_status, $order ) {
return 'on-hold';
}
Code goes in functions.php file of your active child theme (active theme). Tested and works.
So the default order status set by the payment gateway is now "On Hold" instead of "Processing"
In my case,
add_filter( 'woocommerce_cod_process_payment_order_status','change_cod_payment_order_status', 10, 2 );
function change_cod_payment_order_status( $order_status, $order ) {
return 'on-hold';
}
Worked great in WC 4.42 + WP 5.4.1
Thx!
two solution above are same except:
the solution by #LoicTheAztek has 2 arguments in the core function and have a '10' hook priority
the solution by #Jiří-Prek has an arguments in the core function and have a '15' hook priority
but for my WP5.1.1 and WC3.5.7
function change_cod_payment_order_status( $order_status, $order ) {
return 'on-hold';
}
generating an error
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to
function change_cod_payment_order_status()
so I prefer use the code with only one argument in a main function
I need help with a problem-related to plugin "WooCommerce Pay for Payment" which counting some extra fee in shipping. Problem is, that this plugin sets automatically "processing" status in order which causes thanking email for payment (in case of local payment) and don't send email notification about a new order, so customer is confused (I didn't send any money and I received email "thanks for your payment").
I tried this solution: Set WooCommerce order status when order is created from processing to pending
But it only changes order status back to "on-hold" but sends email thank for payment anyway.
Only one thing that I need is to send to the customer in every new order email about a new order, nothing more (I would like to change status to "processing" manually).
Thank you for help, I have no idea how to resolve because I couldn't find PHP file causing a change of status in the plugin.
EDIT: Sorry to all. This was problem of COD in woocommerce plugin. Not Pay for payment as I mentioned. Woocommerce COD automatically set "processing" status.
I found solution for this on github:here
Its the first code.
Based on the answer to this question, this code worked fine for me:
function sv_wc_cod_order_status( $status ) {
return 'on-hold';
}
add_filter( 'woocommerce_cod_process_payment_order_status', 'sv_wc_cod_order_status', 15 );
Updated: The code that you found in Github is outdated, clumsy and complicated, since there is a dedicated filter hook now. You should better try this lightweight and effective code, that will set the default order status for "Cash on delivery" payment gateway (COD) to "On Hold":
add_filter( 'woocommerce_cod_process_payment_order_status', 'change_cod_payment_order_status', 10, 2 );
function change_cod_payment_order_status( $order_status, $order ) {
return 'on-hold';
}
Code goes in functions.php file of your active child theme (active theme). Tested and works.
So the default order status set by the payment gateway is now "On Hold" instead of "Processing"
In my case,
add_filter( 'woocommerce_cod_process_payment_order_status','change_cod_payment_order_status', 10, 2 );
function change_cod_payment_order_status( $order_status, $order ) {
return 'on-hold';
}
Worked great in WC 4.42 + WP 5.4.1
Thx!
two solution above are same except:
the solution by #LoicTheAztek has 2 arguments in the core function and have a '10' hook priority
the solution by #Jiří-Prek has an arguments in the core function and have a '15' hook priority
but for my WP5.1.1 and WC3.5.7
function change_cod_payment_order_status( $order_status, $order ) {
return 'on-hold';
}
generating an error
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to
function change_cod_payment_order_status()
so I prefer use the code with only one argument in a main function
I´m working on my store, all products I´m selling are virtual, because they provide unlock codes.
I´m using plugin named StockUnlock to achieved API access with my providers: till here everything is ok.
In order of the StockUnlock plugin takes action when the client purchased his product the order status must be processing after payment received, but it's not:
When I received the payment the status goes to complete and the plugin don't work. The payment method I´m using is woo-credits (Woo Credits plugin).
How this could be solved, to get a processing status instead of completed?
This behavior comes from the Woo Credit plugin (You could contact authors support threads).
Now you could try this code that will target 'woo_credits' payment gateway only and will update order status back to 'processing', once customer has submitted his order in "Order Received" page (thankyou):
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_paid_order', 999, 1 );
function custom_woocommerce_auto_complete_paid_order( $order_id ) {
// Only for 'woo_credits' payment gateway
if ( ! $order_id || 'woo_credits' != get_post_meta($order_id, '_payment_method', true) )
return;
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Update order status back to 'processing'
$order->update_status( 'processing' );
}
Code goes in function.php file of your active child theme (or active theme).
This code is untested, but could work for you.
I am currently working on a WordPress project using WooCommerce and I need a really specific feature (not included in WooCommerce):
How to increase stock when an order is complete instead of decreasing it ?
What I have found so far is that I might need to use Woocommerce API in order to accomplish that WC_AJAX::increase_order_item_stock();. Nevertheless I am not really comfortable using complex PHP...
Do you have some lines of thinking to accomplish this?
Maybe using a plugin (which I did not find)? Or with raw code?
To sum up everything: I want to build a website for a restaurant with an inventory management and the possibility for cooks to order goods from different suppliers. So when a cook order something from the woocommerce shop page, purchased items's inventory have to increase and not decrease.
I have tried different things like 'WC Vendors' or 'Marketplace' but without success…
Thanks.
You could try This custom function hooked in woocommerce_order_status_completed action hook, that will increase back each product stock with the items quantity of this order when status is set to completed:
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' );
}
}
The code works with simple or variables products that have their own stock management enabled. So may be you might need to make some changes on it, depending on your WooCommerce settings. This is just an example that gives you an idea, a way…
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code don't throw errors on WooCommerce version 2.6.x, and should work.