Woocommerce's wc_get_orders not working in function.php? - php

I am trying to get all orders from woocommerce. Following the instruction on https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query
I put the following code in my function.php
// Get latest 3 orders.
$args = array(
'limit' => 3,
);
$orders = wc_get_orders( $args );
var_dump($orders);
However, it outputs an empty array.
I checked my code and found I actually used wc_get_orders in a hook as below
add_action( 'woocommerce_order_status_changed', 'change_role_on_first_purchase',10,4 );
function change_role_on_first_purchase( $order_id,$old_status, $new_status, $order ) {
$userID = $order->user_id;
$user = new WP_User( $userID );
if ( in_array('subscriber',$user->roles) ){
$args = array(
'customer' => $userID,
'exclude' => array( $order->get_id() ),
'status' => array('completed')
);
$orders = wc_get_orders($args);
if (!$orders && $new_status == "completed"){
$user->set_role('customer');
}
}
}
This is used to change the user's role from subscriber to customer after he places the first order. This function works on my site. So wc_get_orders works here. Why then it is not working in my function.php?

It outputs an empty array because Woocommerce has not yet registered order types/statuses when you're calling wc_get_orders()
Try adding it after init event:
add_action( 'init', 'test_init' );
function test_init() {
// Get latest 3 orders.
$args = array(
'limit' => 3,
);
$orders = wc_get_orders( $args );
var_dump($orders);
}
https://developer.wordpress.org/reference/hooks/init/

Related

Get Woocommerce customer orders

Is is possible to get current and previous customer order? Namely I need Billing Address of current order and Billing Address of previous order per customer.
For example I need to get array of every Customer Order, namely I need Billing Address from every customer order.
So I have some code that print any text at "Edit Order page" in admin panel.
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'edit_woocommerce_order_page', 10, 1 );
function edit_woocommerce_order_page($order){
global $post_id;
$order = new WC_Order( $post_id );
echo '<p><strong>Some text here</strong> ' . get_post_meta($order->get_id(), '_shipping_field_value', true ) . '</p>';
}
As you can see it displays Some text for every user. I guess I should get some array of every customer and display Order array with order ID and Billing Address 1. Check screenshot please
Code above adds text in Edit Order page
Is it possible?
The following function will grab all completed orders if customer is not a guest.
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'edit_woocommerce_order_page', 10, 1 );
function edit_woocommerce_order_page($order){
$customer_id = $order->get_user_id();
//Check if its guest or not
if($customer_id != 0):
$args = array(
'customer_id' => $customer_id,
'status' => array('wc-completed'), //Change if needed
'exclude' => array( $order->get_id() ), // We dont need current order
);
$orders = wc_get_orders( $args );
if($orders):
foreach($orders as $k=>$order):
echo '<p><strong>Some text here</strong>'.$order->get_billing_address_1().'</p>';
endforeach;
endif;
endif;
}
Limit to last 2 orders
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'edit_woocommerce_order_page', 10, 1 );
function edit_woocommerce_order_page($order){
$customer_id = $order->get_user_id();
//Check if its guest or not
if($customer_id != 0):
$args = array(
'customer_id' => $customer_id,
'status' => array('wc-completed'), //Change if needed
'limit' => 2,
);
$orders = wc_get_orders( $args );
if($orders):
foreach($orders as $k=>$order):
echo '<p><strong>Some text here</strong>'.$order->get_billing_address_1().'</p>';
endforeach;
endif;
endif;
}
Getting current order and previous one only
function edit_woocommerce_order_page($order){
$customer_id = $order->get_user_id();
//We need current order id to know where we start
$order_id = $order->get_id();
if($customer_id != 0):
$args = array(
'customer_id' => $customer_id,
'status' => array('wc-completed'), //Change if needed
'return' => 'ids', // Grab all order ids for customer
'posts_per_page' => -1
);
$all_order_ids = wc_get_orders( $args );
//Find current order key
$all_order_id_keys = array_flip(array_keys($all_order_ids));
$current_order_key = array_keys($all_order_ids, $order_id);
//Grab all values from our array
$all_order_id_values = array_values($all_order_ids);
//From all values we look for current order key and we increase that key with 1 to grab prev order id by key
$previous_order_id = $all_order_id_values[$all_order_id_keys[$current_order_key[0]]+1];
$order_args = array(
'post__in' => array($order_id,$previous_order_id),
);
$orders = wc_get_orders( $order_args );
if($orders):
foreach($orders as $k=>$order):
echo $order->get_id(); // For testing
echo '<p><strong>Some text here</strong>'.$order->get_billing_address_1().'</p>';
endforeach;
endif;
endif;
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'edit_woocommerce_order_page', 10, 1 );

how to customise order notes in view order page in woocommerce

please could you help me to find
how to edit automatic order notes generated by system (related to items changed through the order ) i couldn't find it's file
what i want to do
add quantity next to deleted item ( if i have 10 items in order and i have deleted 3 i want to see number of deleted in order notes
add total after deleted or added
Try this:
Solution 1:
add order note from checkout
add_filter( 'woocommerce_checkout_fields', 'woo_custom_order_notes_checkout_fields' );
function woo_custom_order_notes_checkout_fields( $fields )
{
$fields['order']['order_comments']['placeholder'] = 'Your Special notes';
$fields['order']['order_comments']['label'] = 'Add your special note txt';
return $fields;
}
When you place an order with custom text and after the order is placed you will be able to see custom order notes in order detail/edit orders on the dashboard.
Solution 2:
Get/ print order all notes on the order view/edit page after clicking on the update button.
// order comment/notes by id
function woo_get_comment_by_id( $comment_id ) {
$comment = get_comment( intval( $comment_id ) );
if ( ! empty( $comment ) ) {
return $comment->comment_content;
} else {
return '';
}
}
add_action( 'save_post_shop_order', 'wpo_wcol_order_notes', 10, 1 );
function wpo_wcol_order_notes ( $order_id ) {
$args = array(
'post_id' => $order_id,
'orderby' => 'comment_ID',
'order' => 'DESC',
'type' => 'order_note',
// 'number' => 1
);
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
$notes = get_comments( $args );
if($notes){
foreach($notes as $note){
$comment_id = $note->comment_ID ?:0;
if( $comment_id ){
echo woo_get_comment_by_id( $comment_id ).'<br>';
}
}
}
exit; // after test you should removed
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
}
You can also change the action "save_post_shop_order" accordingly as per requirements.

Determine if an WooCommerce order contains order notes while using "woe_order_export_started" hook

The woe_order_export_started filter hook is related to a plugin
This code is used for exporting orders with total > 10
add_filter( 'woe_order_export_started', function ( $order_id ) {
$order = new WC_Order($order_id);
return ($order->get_total() > 10.00) ? $order_id: false;
});
I am trying to create a php code to find out whether the order has order note or not, and to ignore the orders which has no order note.
I found out the code to get the order notes
$args = array(
'post_id' => $order->id,
'approve' => 'approve',
'type' => 'order_note',
'search' => 'Order status changed from Pending Payment to Processing.',
);
// woocommerce hides such records by default
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10 );
$notes = get_comments( $args );
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
How to I implement this with the woe_order_export_started filter hook to determine if the order has order note or not.
Basically I want to avoid exporting the orders which has no order note. So it should return false if there is no order note.
The following answer returns false if there are no order notes, while using the woo_order_export_started filter hook
function filter_woe_order_export_started( $order_id ) {
// Get order notes
$notes = wc_get_order_notes( array(
'order_id' => $order_id,
'order_by' => 'date_created',
'order' => 'ASC',
));
// Notes is empty
if ( empty( $notes ) ) {
return false;
}
return $order_id;
}
add_filter( 'woe_order_export_started', 'filter_woe_order_export_started', 10, 1 );

Change user role based on WooCommerce yearly orders count

I'm trying to implement a feature where customers receive a new user role after a certain amount of orders have been made, but all those orders must have been made within the same year.
I was able to assign the user role based on nth number of orders but can't seem to go beyond to where the date needs to be taken into consideration, can someone point me in the right direction or point out what I might be missing.
This is what I have tried so far.
function change_user_role_on_order_status_completed( $order_id ) {
$order = new WC_Order( $order_id );
$user_id = $order->user_id;
$order_this_year = false;
$current_date = date('Y');
$total_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
) );
if ( $total_orders > 1 ) {
foreach ($order->get_items() as $item_key => $item_values):
// Get the item date
if ($item_date = $item_values->get_date_completed()->format ('Y') == $current_date) {
$order_this_year = true;
}
endforeach;
if ($order_this_year) {
$user = new WP_User( $order->user_id );
// Set role editor
$user->set_role( 'customer_club' );
}
}
}
add_action( 'woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 1 );
Using WC_Order_Query here is a much lighter and simple way to change the user role based on yearly orders count:
add_action( 'woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 2 );
function change_user_role_on_order_status_completed( $order_id, $order ) {
// Here set the minimal order count
$min_orders_count = 3;
// The WC_Order_Query
$queried_orders = wc_get_orders( array(
'limit' => -1,
'customer_id' => $order->get_customer_id(),
'date_paid' => '>=' . date('Y') . '-01-01', // or 'date_created'
'return' => 'ids'
) );
if ( sizeof($queried_orders) >= $min_orders_count ) {
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Change the user role
$user->set_role( 'customer_club' );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Woocommerce - Copy New Order Details to New Table

I found the below script somewhere on here before and having trouble getting it to work. Basically I want to copy basic order details into a new table (which is in the same database), so I can run some reports off of it from non wordpress page. I have changed the table name and fields and copied this into my functions.php in the theme. But it doesnt seem to do anything. Any help would be great, im really stuck. I'm running woocommerce 2.2.8 if that makes any difference.
function add_neworders ($order_id) {
global $woocommerce;
$order = new WC_Order( $order_id );
$total = $order->order_total;
$date = $order->order_date;
global $wpdb;
$table = $wpdb->prefix . 'finacedata';
$wpdb->insert($table, array(
'desctipion' => $name,
'status' => '2',
'date' => $date,
'amount' => $total,
'invoice' => $order_id,
));
add_action( 'woocommerce_new_order', 'add_neworders' );}
This is probably a late answer, but the woocommerce_new_order action runs when the order is created, but the data is not populated just yet, so everything is empty.
Use the woocommerce_checkout_order_processed action instead, which runs when the order is created and all of the order data(like line items) are stored.
you can't add add_action into function. put outside the function:
function add_neworders ($order_id) {
global $woocommerce;
$order = new WC_Order( $order_id );
$total = $order->order_total;
$date = $order->order_date;
global $wpdb;
$table = $wpdb->prefix . 'finacedata';
$wpdb->insert($table, array(
'desctipion' => $name,
'status' => '2',
'date' => $date,
'amount' => $total,
'invoice' => $order_id,
));
}
add_action( 'woocommerce_new_order', 'add_neworders' );

Categories