Kolumna z datą realizacji zamówienia

Dzisiaj będzie trochę bardziej zawile bo zaczynają się schody związane z ulepszeniem magazynu woocommerce. HPOS czyli High-Performance Order Storage. Nowa baza danych do przechowywania zamówień, która umożliwia bezproblemową skalowalność w dużych i szybko rozwijających się sklepach. To tyle definicja. A praktyka sobie bo w wielu przypadkach to co miało działać wstecznie nagle zaczęło przysparzać problemów. Nie mówię tutaj nawet o tym, że przy okazji usuwania zamówień z tabeli postów, znikają również dane z tabeli post_meta. Kilka z dotychczas działających funkcji (pomimo zapewnień woocommerce) nagle przestaje działać.

Jedną z takich funkcji (filtrów) jest manage_edit-shop_order_columns, który możemy zamienić na manage_woocommerce_page_wc-orders_columns

Generalnie, musimy wymienić wszystkie haki i filtry z shop_order_posts na woocommerce_page_wc-orders.

Najpierw kod, który działa w momencie kiedy mamy jeszcze stary magazyn bez HPOS.

Dodajemy nową kolumnę w panelu administracyjnym WooCommerce:

add_filter( 'manage_edit-shop_order_columns', 'gc_new_order_column' );
function gc_new_order_column( $columns ) {
	$reordered_columns = array();
	foreach( $columns as $key => $column){
        $reordered_columns[$key] = $column;
        if( $key ==  'order_total' ){
            $reordered_columns['zrealizowane_column'] = 'Data wysyłki';
        }
    }
    return $reordered_columns;
}

Teraz wypełniamy nową kolumnę danymi pobranymi z metadanych zamówienia:

add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id )
{
    switch ( $column )
    {
        case 'zrealizowane_column' :
		$completedDate = get_post_meta( $post_id, '_completed_date', true );
                echo $completedDate;
            break;
    }
}

I w starym magazynie to by było na tyle. Ale przy HPOS nie dość że zmienia się nam hook to, jak wspomniałem wcześniej znikają nam post_meta.

Jeśli korzystasz z HPOS (High-Performance Order Storage), WooCommerce przechowuje datę zmiany statusu zamówienia na „zrealizowane” (completed) w nowej strukturze tabeli bazy danych. Wcześniej ta data była zapisana w wp_postmeta jako _completed_date, ale teraz przechowywana jest w tabeli wc_orders.

Aby pobrać datę zmiany statusu bez zapisywania jej w metadanych zamówienia, musimy użyć nowego sposobu pobierania tej wartości.

Żeby nie iść na łatwiznę, jedynie podmieniając hooka na manage_woocommerce_page_wc-orders_columns, pójdziemy jeszcze dalej – czyli krócej :). Samo utworzenie kolumny w panelu zamówień Woocommerce będzie wyglądało tak:

add_filter('woocommerce_admin_list_table_column_headers', function ($columns) {
    $columns['data_zmiany_statusu'] = __('Data zmiany statusu', 'woocommerce');
    return $columns;
});

WooCommerce HPOS przechowuje zamówienia inaczej, więc nie możemy już korzystać z manage_shop_order_posts_custom_column. Zamiast tego używamy woocommerce_admin_list_table_column_value.

add_filter('woocommerce_admin_list_table_column_value_data_zmiany_statusu', function ($value, $order) {
    if (!is_a($order, 'WC_Order')) {
        return '-';
    }

    // Pobranie daty zakończenia zamówienia (wc_orders.created_at dla HPOS)
    $data_zmiany = $order->get_date_completed();

    return $data_zmiany ? esc_html($data_zmiany->date('Y-m-d H:i:s')) : '-';
}, 10, 2);

🎯 Efekt końcowy

✔️ Kolumna „Data zmiany statusu” pojawi się w WooCommerce → Zamówienia.
✔️ Nie zapisujemy daty w postmeta – pobieramy ją bezpośrednio z WooCommerce HPOS!
✔️ Kod działa zarówno na HPOS, jak i w starszych wersjach WooCommerce!

Teraz nie trzeba ręcznie zapisywać daty – WooCommerce zrobi to automatycznie. 🚀

A może chcesz dodać sortowanie tej kolumny? 😊

Ustawienie kolumny jako sortowalnej

WooCommerce korzysta z filtra woocommerce_admin_list_table_sortable_columns, aby określić, które kolumny można sortować. Dodajemy obsługę sortowania dla kolumny „Data zmiany statusu”:

add_filter('woocommerce_admin_list_table_sortable_columns', function ($sortable_columns) {
    $sortable_columns['data_zmiany_statusu'] = 'date_completed'; // Klucz sortowania
    return $sortable_columns;
});

Obsługa sortowania w zapytaniu SQL

WooCommerce HPOS zapisuje datę zakończenia zamówienia w polu date_completed w tabeli wc_orders, więc musimy dostosować sposób sortowania wyników:

add_filter('woocommerce_order_data_store_cpt_get_orders_query', function ($args, $query) {
    if (isset($query['orderby']) && 'date_completed' === $query['orderby']) {
        $args['orderby'] = 'date_completed'; // Sortowanie po polu date_completed
    }
    return $args;
}, 10, 2);

🔥 Efekt końcowy

✔️ Dodana kolumna „Data zmiany statusu” jest teraz sortowalna
✔️ Dane są pobierane z HPOS (wc_orders.date_completed), a nie z postmeta
✔️ Kod działa zarówno z HPOS, jak i ze starszym systemem zamówień WooCommerce

Teraz możesz kliknąć nagłówek kolumny „Data zmiany statusu”, aby posortować zamówienia według daty zmiany statusu na „Zrealizowane”. 🚀

Gdyby powyższy kod nie zadziałał to podaję sprawdzone u mnie rozwiązanie z innym filtrem woocommerce_shop_order_list_table

add_filter( 'woocommerce_shop_order_list_table_columns', function ( $columns ) {
	$columns['data_wysylki'] = 'Data wysyłki';
	return $columns;
} );

add_action( 'woocommerce_shop_order_list_table_custom_column', function ( $column, $order ) {
	if ( 'data_wysylki' !== $column ) {
		return;
	}
		// Pobranie daty zakończenia zamówienia
                $data_zmiany = $order->get_date_completed();
		echo $data_zmiany ? esc_html($data_zmiany->date('Y-m-d')) : '-';
}, 10, 2 );

I jeszcze sortowanie pamiętając, że to kolumna typu datetime:

add_filter( 'woocommerce_shop_order_list_table_sortable_columns', function ( $sortable_columns ) {
	$sortable_columns['data_wysylki'] = 'date_completed'; // Klucz dla sortowania
	return $sortable_columns;
} );

add_filter( 'woocommerce_shop_order_list_table_set_order_query_args', function ( $query_args, $args ) {
    if ( isset( $args['orderby'] ) && 'date_completed' === $args['orderby'] ) {
        $query_args['orderby'] = 'date_completed'; // HPOS obsługuje to pole w `wc_orders`
        $query_args['order'] = $args['order']; // DESC lub ASC
    }
    return $query_args;
}, 10, 2 );
Przewijanie do góry