Get Woocommerce customer orders - php

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

Related

Woocommerce's wc_get_orders not working in function.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/

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.

How to get purchase date from woocommerce order?

I have a product loop in Woocommerce. If a customer has purchased a product before, I would like to replace the purchase product button with a message and the date of the order. For example.
"You purchased this product on Jan. 15, 2016"
I can get the product id and I can get the current user id, but can't figure out how to use those pieces of info to pull order ids.
$postid = get_the_ID();
$current_user = wp_get_current_user();
$has_product = wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->id);
Ideas?
You can use this function below
function _cmk_check_ordered_product( $id ) {
// Get All order of current user
$orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types( 'view-orders' ),
'post_status' => array_keys( wc_get_order_statuses() )
) );
if ( !$orders ) return false; // return if no order found
$all_ordered_product = array(); // store products ordered in an array
foreach ( $orders as $order => $data ) { // Loop through each order
$order_data = new WC_Order( $data->ID ); // create new object for each order
foreach ( $order_data->get_items() as $key => $item ) { // loop through each order item
// store in array with product ID as key and order date a value
$all_ordered_product[ $item['product_id'] ] = $data->post_date;
}
}
if ( isset( $all_ordered_product[ $id ] ) ) { // check if defined ID is found in array
return 'You purchased this product on '. date('M. d, Y', strtotime( $all_ordered_product[ $id ] ) );
} else {
return 'Product Never Purchased';
}
}
e.g.
Showing message on single product page echo _cmk_check_ordered_product( get_the_ID() );

Categories