Add customer note from another script in WooCommerce - php

I have a script that changes the status of orders based on our ERP system.
In addition to that, we need to add customer notes. I found the way to do it:
$order->add_order_note($note);
$order->save();
Unfortunately this won't work outside the order edit screen, I tried to run it from my custom plugin. (source)
If I do it via $order->update_status($status, $note); it only updates the status.
Is there a way to add a note outside the edit screen? (Including e-mailing the customer)

If the note is for the customer (and has to be visible for him) you need to use instead the WC_Order method set_customer_note() (or both):
$order->set_customer_note($note);
// $order->add_order_note($note);
$order->save();
Or:
$order->set_customer_note($note);
$order->update_status($status, $note);
This need to be done before saving the order data or updating the order status.
To re-send the email notification to the customer (if needed) you can use from the current order ID:
$emails = WC()->mailer()->get_emails();
$emails['WC_Email_Customer_Completed_Order']->trigger( $order_id );
// OR: $emails['WC_Email_Customer_Processing_Order']->trigger( $order_id );

//Pass order id from hook or function with $order_id
$order = new WC_Order( $order_id );
$note = 'Add note here';
$order->add_order_note($note);
$order->save();
I'm constructing a new class of order. Passing the order ID and order note and then saving the order again.
This is how we update our site from our ERP. But as Loic said this method creates a private note. Use his
$order->set_customer_note($note);
to create a customer note.

Related

Trying to find the right hook for WooCommerce Order Submission

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

Add custom profile data to order [duplicate]

Is it possible to automatically copy the value of a Customer's custom field to an Order's custom field when this customer places the order?
Should it be done using any plugin/extension or thru customized coding behind the scenes?
This custom field does not need to be displayed on customer order view. We just need it to distinguish whether the order was placed by Consumer or Wholesale when we get it thru API.
I'm totally new in this system, i did a lot of research but couldn't find any direction for this.
Any advice/suggestion would be very appreciated.
You can use woocommerce_thankyou hook to add this user data to the order meta data:
add_action( 'woocommerce_thankyou', 'orders_from_processing_to_pending', 10, 1 );
function orders_from_processing_to_pending( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
$user_id = get_current_user_id();
//Set HERE the meta key of your custom user field
$user_meta_key = 'some_meta_key';
// Get here the user custom field (meta data) value
$user_meta_value = get_user_meta($user_id, $user_meta_key, true);
if ( ! empty($user_meta_value) )
update_post_meta($order_id, $user_meta_key, $user_meta_value);
else
return;
}
Code goes in function.php file of your active child theme (active theme or in any plugin file).
This code is tested and works.
After, if you want to display that value on admin edit order backend or in frontend customer view order and emails notifications, you will have to use some more code and some other hooks…

WooCommerce - Order Status for Pending Payment Reducing Stock

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');

Woocommerce new order then save

I need to create a function that looks for all the new orders entered in woocommerce and then just update this order without changing anything. (like if you clicked on the order and then clicked update with everything remaining the same)
The reason for this is that I'm bringing orders from another source into woocommerce but the plugin to export them to another platform isn't listening for these external orders until they are updated even if nothing changes.
I know I have to use the woocommerce_new_order hook to listen for the new orders coming in but how can I just update it without changing anything?
function custom_woocommerce_order($order_id) {
if (!$order_id) {
return;
}
//Will this work for what I need?
$order_id = $order->save();
//Or should I do this instead?
$order = wc_get_order($order_id);
do_action( 'woocommerce_update_order', $order );
}
add_action('woocommerce_new_order', 'custom_woocommerce_order');

Availability of Woocommerce Session after checkout?

I'm currently using a Woocommerce session to save information that the user inputs on the cart page which affects a fee added to the transaction.
I need to be able to access this information right after the order has been completed to make necessary updates to the user's account.
I figured woocommerce_thankyou would be a good hook to use, but unfortunately the session only seems to be available half of the time.
Are there any better hooks to use where I could confirm that the purchase had been completed and the session information would be available?
You need to save that session data as custom order meta data, to be able to use it afterwards (replace my_key, in the code below, with the correct session key):
// Add custom order meta data with temporary data from WC_Session
add_action( 'woocommerce_checkout_create_order', 'add_session_data_as_custom_order_meta_data', 10, 2 );
function add_session_data_as_custom_order_meta_data( $order, $data ) {
if ( $session_data = WC()->session->get('my_key') ) {
$order->update_meta_data( '_session_data', $session_data );
}
}
Code goes on function.php file of your active child theme (or theme). Tested and works.
Then to access the data you will use th WC_Data method get_meta() on the WC_Order Object:
$session_data = $order->get_meta('_session_data');
Or also using get_post_meta() function from a defined order Id:
$session_data = get_post_meta( $order_id, '_session_data', true );

Categories