I'm trying to add custom code to enable admin orders table sorting by order status. The sorting works, but it looks like it doesnt sort properly by asc / desc. I have written this code, but for some reason the sorting is random, it doesn't sort by asc and desc..
// Make custom column sortable
add_filter( "manage_edit-shop_order_sortable_columns", 'shop_order_column_meta_field_sortable' );
function shop_order_column_meta_field_sortable( $columns )
{
$meta_key = 'order_status';
return wp_parse_args( array('order_status' => $meta_key), $columns );
}
// Make sorting work properly (by numerical values)
add_action('pre_get_posts', 'shop_order_column_meta_field_sortable_orderby' );
function shop_order_column_meta_field_sortable_orderby( $query ) {
global $pagenow;
if ( 'edit.php' === $pagenow && isset($_GET['post_type']) && 'shop_order' === $_GET['post_type'] ){
$orderby = $query->get( 'orderby');
$meta_key = '_order_status';
if ('_order_status' === $orderby){
$query->set('meta_key', $meta_key);
$query->set('orderby', 'meta_value_num');
}
}
}
Related
How can the default sorting of the Woocommerce order list be changed. For now each time I enter the order page, orders are displayed as DESC. I would like it to be ASC by default each time I enter the order page. Can anyone help?
As I found another custom order solution in the forum:
sort-orders-by-paid-date-in-woocommerce-admin-order-list
I edited the code mentioned in there to the following, which worked out:
function action_parse_query( $query ) {
global $pagenow;
// Initialize
$query_vars = &$query->query_vars;
// Only on WooCommerce admin order list
if ( is_admin() && $query->is_main_query() && $pagenow == 'edit.php' && $query_vars['post_type'] == 'shop_order' ) {
// Set
$query->set( 'orderby', 'date' );
$query->set( 'order', 'ASC' );
}
}
add_action( 'parse_query', 'action_parse_query', 10, 1 );
These code will do the work.
add_filter( 'woocommerce_order_query_args', function ( $args ) {
$args['order'] = 'ASC';
return $args;
} );
I want to hide order statuses in the WooCommerce order status dropdown under specific scenarios:
If status is pending payment hide completed
If status is processing hide pending payment
I still want to display all these order statuses in the order overview list.
All I can find is to unset an order status completely:
function so_39252649_remove_processing_status ($statuses) {
if (isset($statuses['wc-processing'])) {
unset($statuses['wc-processing']);
}
return $statuses;
}
add_filter('wc_order_statuses', 'so_39252649_remove_processing_status');
But this will of course also remove it from the order overview list, I just want to hide it in the dropdown on the order edit page, but I cant find a hook for this.
Is jQuery my only choice for this?
You can use the following, comments with explanations added in the code.
So you get:
// Admin order edit page: order status dropdown
function filter_wc_order_statuses( $order_statuses ) {
global $post, $pagenow;
// Target edit pages
if( $pagenow === 'post.php' && isset($_GET['post']) && $_GET['action'] == 'edit' && get_post_type($_GET['post']) === 'shop_order' ) {
// Get ID
$order_id = $post->ID;
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Is a WC order
if ( is_a( $order, 'WC_Order' ) ) {
// Get current order status
$order_status = $order->get_status();
// Compare
if ( $order_status == 'pending' ) {
unset( $order_statuses['wc-completed'] );
} elseif ( $order_status == 'processing' ) {
unset( $order_statuses['wc-pending'] );
}
}
}
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'filter_wc_order_statuses', 10, 1 );
Departing from the following tutorial: "Columns in WooCommerce", the intention is to make the coupon amount column sortable based on amount.
Making it sortable seems to be successful with my already written code. Nevertheless, the rule to sort goes wrong.
I've tried several things before but the sort code is not applied after clicking,
Who would like to take a closer look?
What I've used so far:
add_filter('manage_edit-shop_coupon_sortable_columns', 'misha_sortable');
function misha_sortable( $sortable_columns ){
$sortable_columns['amount'] = 'amount';
return $sortable_columns;
}
add_action( 'pre_get_posts', 'misha_filter' );
function misha_filter( $query ) {
// if it is not admin area, exit the filter immediately
if ( ! is_admin() ) return;
if( empty( $_GET['orderby'] ) || empty( $_GET['order'] ) ) return;
if( $_GET['orderby'] == 'amount' ) {
$query->set('meta_key', 'amount' );
$query->set('orderby', 'meta_value'); // or meta_value_num
$query->set('order', $_GET['order'] );
}
return $query;
}
The correct metakey is coupon_amount instead of amount
So this should suffice
// Make column sortable
function filter_manage_edit_shop_coupon_sortable_columns( $columns ) {
$columns['amount'] = 'amount';
return $columns;
}
add_filter( 'manage_edit-shop_coupon_sortable_columns', 'filter_manage_edit_shop_coupon_sortable_columns', 10, 1 );
// Fires after the query variable object is created, but before the actual query is run.
function action_pre_get_posts( $query ) {
// If it is not admin area, exit the filter immediately
if( ! is_admin() ) return;
// Get orderby
$orderby = $query->get( 'orderby' );
// Set query
if( $orderby == 'amount' ) {
$query->set( 'meta_key', 'coupon_amount' );
$query->set( 'orderby', 'meta_value_num' );
}
}
add_action( 'pre_get_posts', 'action_pre_get_posts', 10, 1 );
I'm looking to allow the Order Again functionality to all statuses. By default WooCommerce only allows orders with a status of COMPLETED this functionality. It seems to be a two step process as the first step requires the button being shown to the user, this is completed by editing this file:
wc-template-functions.php
With this snippit of code:
function woocommerce_order_again_button( $order ) {
//if ( ! $order || ! $order->has_status( 'completed' ) || ! is_user_logged_in() ) {
// Allow 'Order Again' at all times.
if ( ! $order || ! is_user_logged_in() ) {
return;
}
wc_get_template( 'order/order-again.php', array(
'order' => $order
) );
}
By commenting out the validation of the $order->has_status() method, I'm able to show the button on the page. However, when trying clicking the Order Again button, it still does a check before adding the items to the cart.
Can anyone tell me where this code is stored to do a preliminary check on the $order->has_status()?
You can simply add difference order status to filter woocommerce_valid_order_statuses_for_order_again.
add_filter( 'woocommerce_valid_order_statuses_for_order_again', 'add_order_again_status', 10, 1);
function add_order_again_status($array){
$array = array_merge($array, array('on-hold', 'processing', 'pending-payment', 'cancelled', 'refunded'));
return $array;
}
Since the OP's original question, WooCommerce has added a filter to these statuses. The function can be found in includes/wc-template-functions.php
https://docs.woocommerce.com/wp-content/images/wc-apidocs/function-woocommerce_order_again_button.html
/**
* Display an 'order again' button on the view order page.
*
* #param object $order
* #subpackage Orders
*/
function woocommerce_order_again_button( $order ) {
if ( ! $order || ! $order->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_order_again', array( 'completed' ) ) ) || ! is_user_logged_in() ) {
return;
}
wc_get_template( 'order/order-again.php', array(
'order' => $order,
) );
}
So in order to filter the statuses you could do something like this (wc_get_order_statuses() just returns all order statuses in this case; you can set the $statuses variable to an array of an statuses you would like):
add_filter('woocommerce_valid_order_statuses_for_order_again', function( $statuses ){
$statuses = wc_get_order_statuses();
return $statuses;
}, 10, 2);
In advance many thanks for read this question!
I have order my post by a custom field (eslora), but when apply the filter (category) this sort is broken.
Some one know how can order my post on this way by default.
Best regards!
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'event' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
$query->set('orderby', 'meta_value_num');
$query->set('meta_key', 'eslora');
$query->set('order', 'ASC');
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');