woocommerce / woocommerce

A customizable, open-source ecommerce platform built on WordPress. Build any commerce solution you can imagine.
https://woocommerce.com
9.25k stars 10.73k forks source link

Adding a shipping_method to WC_Order_Query #26727

Open wppunk opened 4 years ago

wppunk commented 4 years ago

Is your feature request related to a problem? Please describe. I need to get all orders with the something shipping method.

Describe the solution you'd like I want to use WC_Order_Query to get an order with the something shipping method.

$query  = new WC_Order_Query(
    [
        'shipping_method' => 'my_shipping_method',
    ]
);
$this->items = $query->get_orders();

So in WP_Order_Query we can get by payment method but can't by shipping method.

Describe alternatives you've considered I'm using a SQL query for this. But its not better solution.

SELECT woim.meta_value as rate_id, woi.order_item_name as rate_name, woi.order_id
    FROM wp_woocommerce_order_itemmeta as woim
    INNER JOIN wp_woocommerce_order_items as woi ON woim.order_item_id = woi.order_item_id
    WHERE woi.order_item_type = 'shipping'
    AND woim.meta_value = 'method_name'
    ORDER BY woi.order_id
seredniy commented 4 years ago

Good idea! In my old plugin I use some variant of sql code above. But it is not usable...

ObliviousHarmony commented 4 years ago

Hi @wppunk,

Thank you for taking the time to share this idea, we really appreciate your help.

While this is clearly a great improvement/idea we won’t be able to tackle it in the upcoming weeks. We’re going to add it to our backlog where it will be considered for future releases.

Stay tuned for updates.

wppunk commented 4 years ago

@ObliviousHarmony I did it using default WP_Query hooks. This can somewhere help for you.

add_filter( 'posts_join', function ( $join, $query ) {
    if ( ! $query->get( 'shipping_method' ) ) {
        return $join;
    }
    global $wpdb;
    $join .= ' LEFT JOIN ' . $wpdb->prefix . 'woocommerce_order_items as woi ON wp_posts.ID = woi.order_id';
    $join .= ' LEFT JOIN ' . $wpdb->order_itemmeta . ' as woim ON woi.order_item_id = woim.order_item_id';

    return $join;
}, 10, 2 );
add_filter( 'posts_where', function ( $where, WP_Query $query ) {
    if ( ! $query->get( 'shipping_method' ) ) {
        return $where;
    }
    global $wpdb;
    $where .= ' AND woi.order_item_type = "shipping"';
    $where .= ' AND woim.meta_key = "method_id"';
    $where .= $wpdb->prepare( ' AND woim.meta_value = %s', $query->get( 'shipping_method' ) );

return $where;
}, 10, 2 );

P.S. Also I don't understand why you have $wpdb->order_itemmeta, but don't have a $wpdb->order_items