Hide orders with status (Pending Payment) on WooCommerce My Account page - php

Inspired by the thread 'Hiding order status in My Account recent orders list page'
I tried to hide orders with status (Pending Payment) on the 'My Account' page.
I modified the code slightly, but I can't get it to work.
add_filter('woocommerce_my_account_my_orders_actions', 'custom_removing_order_status_pending_payment', 10, 1);
function custom_removing_order_status_pending_payment( $order ){
unset($order['wc-pending']);
return $order;
}
I really appreciate any help. Thank you.

Right now you are using the woocommerce_my_account_my_orders_actions filter which will let you filter the buttons in the 'Action' column on the 'My Account' page.
If you want to filter out certain order statuses from the order list you will have to use the woocommerce_my_account_my_orders_query filter.
add_filter( 'woocommerce_my_account_my_orders_query', 'unset_pending_payment_orders_from_my_account', 10, 1 );
function unset_pending_payment_orders_from_my_account( $args ) {
$statuses = wc_get_order_statuses();
unset( $statuses['wc-pending'] );
$args['post_status'] = array_keys( $statuses );
return $args;
}

The accepted answer is mostly, OK, however, it relies on WooCommerce saving Orders as a WordPress custom post type, and there's been for a while a conversation about moving orders to their own custom table to improve performance and scalability of WooCommerce-powered stores.
As a general rule, it is better to use WooCommerce's specific methods and parameters.
The filter woocommerce_my_account_my_orders_query uses wc_get_orders which says to use 'status' as parameter, and not 'post_status'
The updated answer using WC_Order_Query would be
add_filter( 'woocommerce_my_account_my_orders_query', 'unset_pending_payment_orders_from_my_account', 10, 1 );
function unset_pending_payment_orders_from_my_account( $args ) {
$statuses = wc_get_order_statuses();
unset( $statuses['wc-pending'] );
$args['status'] = array_keys( $statuses );
return $args;
}

Related

Saving a product meta field to order item meta in WooCommerce

First time posting...so hopefully I've done this correctly. :)
I'm currently working on a snippet to save a custom product field (purchase price) into the order item meta. The reason that we want to do this is that the purchase price changes during the time where orders are accepted. In order to produce accurate reporting - we need to know what the purchase price field (custom product field) was set to when the order was placed. Simply exporting the custom field (_wcj_purchase_price) gives the current value, which may not be current.
The custom field that stores the purchase price is called _wcj_purchase_price and I am trying to create a custom order item meta field called _purchase_price which is added at the time the order is created.
This is the code that I've got so far, from my attempts, but it's not working quite right. I am sure the answer is obvious to someone, but I'm very stuck at the moment!
add_action( 'wc_add_order_item_meta', 'save_item_sku_order_itemmeta', 10, 3 );
function save_item_sku_order_itemmeta( $item_id, $values, $cart_item_key ) {
$purchasep = get_post_meta( $values[ 'product_id' ], '_wcj_purchase_price', true );
wc_add_order_item_meta( $item_id, '_purchase_price', $purchasep , false );
}
Any ideas or advice? Please let me know if anything is unclear.
Thank you very much!
Are you sure that there is a filter called "wc_add_order_item_meta"?
Correct filter for this case can be woocommerce_new_order.
add_action('woocommerce_new_order', function ($order_id) {
// your code here
}, 10, 1);
For exampe, you can use such code:
add_action('woocommerce_new_order', function ($order_id) {
$order = wc_get_order( $order_id );
foreach( $order->get_items() as $item_id => $item ){
$product_id = $item->get_product_id();
$purchasep = get_post_meta( $product_id, '_wcj_purchase_price', true );
wc_add_order_item_meta($item_id, '_purchase_price', $purchasep , false );
}
}, 10, 1);

How to sort products in category by post id in WooCommerce?

In shop, some products belong to multiple categories. This makes default WooCommerce ordering not working, because if one product is first in category A then other product can't be first in category B if both belong to the same category.
I want to find a way to sort products in shop categories by post id in particular order I want ( I will supply IDs).
So far I came up with:
add_filter( 'woocommerce_get_catalog_ordering_args', 'my_ordering_function', 20, 1 );
function my_ordering_function( $args ) {
$product_category = 'my-category';
if( ! is_product_category($product_category) ) return $args;
$args['post__in'] = array( 74, 116, 3565, 3563 );
$args['orderby'] = 'post__in';
$args['order'] = 'ASC';
return $args;
}
This code should do the job, but after examining woocommerce_get_catalog_ordering_args source code, it looks like post__in is not even supported.
Any ideas on how to dictate my own product order per category?
With your approach, you can do this in the parent function of the function that uses the woocommerce_get_catalog_ordering_args filter.
The function you are looking for is product_query, in this function you have an action hook woocommerce_product_query. For your use case, something like this would work.
function my_ordering_function( $q, $this ) {
$q->set( 'post__in', array( 74, 116, 3565, 3563 ) );
$q->set( 'orderby', 'post__in' );
}
add_action( 'woocommerce_product_query', 'my_ordering_function', 10, 2 );
P.S. This function is also in the same file that you referenced. You can have a look there to see how it works.

Customize Woocommerce PIP add row to invoice

I have Woocommerce website that does not show VAT, and clients don't want that to change.
I have purchased WooCommerce Print Invoices/Packing Lists.
I would like to add an additional row to the bottom of the table with a calculation of how much VAT was in the invoice using a simple calculation based on the invoice total.
I have achieved this by editing order-table.php but would prefer to add this by adding a filter to functions.php.
I have looked at https://docs.woocommerce.com/document/woocommerce-print-invoice-packing-list/ but can not seem to achieve what I need.
Can anyone point me in the right direction?
Thanks
I found a filter after scouring through the code. I even added some extra code to reorder the values so that the VAT appears before the total. If you don't want it like that I will post the solution without reordering also. I've added in a dummy price of $10 which you can replace with your calculation.
function modify_wc_pip_document_table_footer( $rows, $type, $order_id ) {
$tmp_rows = array();
$tmp_rows['cart_subtotal'] = $rows['cart_subtotal'];
$tmp_rows['payment_method'] = $rows['payment_method'];
$tmp_rows['vat'] = array( 'vat_total' => '<strong class="order-order_total">VAT Total:</strong>',
'value' => wc_price(10)
);
$tmp_rows['order_total'] = $rows['order_total'];
return $tmp_rows;
}
add_filter( 'wc_pip_document_table_footer', 'modify_wc_pip_document_table_footer', 10, 3 );
Without reordering
function modify_wc_pip_document_table_footer( $rows, $type, $order_id ) {
$order = wc_get_order( $order_id );
$order_total = $order->get_total();
$rows['vat'] = array( 'vat_total' => '<strong class="order-order_total">VAT Total:</strong>',
'value' => wc_price(600)
);
return $rows;
}
add_filter( 'wc_pip_document_table_footer', 'modify_wc_pip_document_table_footer', 10, 3 );

Alternative way to orderby grouped product child since filter `woocommerce_grouped_children_args` was removed from WooCommerce 3

In Wordpress Woocommerce I have created a grouped product, with lots of sub products (children) in it. I tried searching everywhere, but I can not find a working solution how to orderby them by either SKU or product name. It seems that it's orderby is generated by "Menu Order" only. Although as I have 30+ sub products in these multiple grouped products, it would be extremely time wasting to order them by Menu Order value.
I tried the following code, but it seems that it worked in WC 2.5, but not 3.0+ .
add_filter( 'woocommerce_grouped_children_args',
'so_22661392_grouped_children_args' );
function so_22661392_grouped_children_args( $args ){
$args['meta_key'] = 'sku';
$args['orderby'] = 'meta_value';
$args['order'] = 'ASC';
return $args;
}
I also searched Google for explanations but could not find any. I tried to clear transients, this doesn't work as well:
WooCommerce>System Status>Tools>Clear Transients
The grouped product can be seen on https://plastmet.ee/uus/toode/umartoru-kork-zzo-pealekaiv/ . The html table should match the children below, but it does not. SKU for children is "563/9005", "567/9005" etc..
Any help would be greatly appreciated!
Hopefully I understand the problem correctly:
If we have overriden the template file single-product/add-to-cart/grouped.php, then we could use e.g.:
if( $grouped_products )
usort( $grouped_products, 'wc_products_array_orderby_title' );
to sort the grouped products by title, instead of the default menu ordering.
We could also unregister:
add_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
with a custom callback instead.
As a last resort one could override the woocommerce_grouped_add_to_cart() function, e.g. within a plugin, to change the menu ordering.
It's defined as:
if ( ! function_exists( 'woocommerce_grouped_add_to_cart' ) ) {
function woocommerce_grouped_add_to_cart() {
global $product;
$products = array_filter( array_map( 'wc_get_product', $product->get_children() ) );
if ( $products ) {
usort( $products, 'wc_products_array_orderby_menu_order' );
wc_get_template( 'single-product/add-to-cart/grouped.php', array(
'grouped_product' => $product,
'grouped_products' => $products,
'quantites_required' => false,
) );
}
}
}
where one could e.g. use wc_products_array_orderby_title instead.

Woocommerce: How to Add extra fee for First Order

I am trying to add Extra Fee in the total of cart/order amount only if this is first order of Customer.
I searched a lot online but I still did not find any specific solution yet.
Please someone suggest/guide the best solution to perferm this.
Thanks
You use the cart class' add_fee() method to add a fee. There's no built-in way to know how many orders a customer has made, so we can try to track that via a user meta field called _number_order.
function so_27969258_add_cart_fee() {
$orders = intval( get_user_meta( get_current_user_id(), '_number_orders', true ) );
if( $orders < 1 ){
WC()->cart->add_fee( __( 'First time fee', 'your-plugin'), 100 );
}
}
add_action( 'woocommerce_before_calculate_totals', 'so_27969258_add_cart_fee' );
If we don't actually update the _number_orders key, then it will always be null/empty/zero and the user will always be charged the first time fee. So we can try to update that key when the user completes payment.
function so_27969258_track_orders_per_customer(){
$orders = intval( get_user_meta( get_current_user_id(), '_number_orders', true ) );
$orders = $orders + 1;
update_user_meta( get_current_user_id(), '_number_orders', $orders );
}
add_action( 'woocommerce_payment_complete', 'so_27969258_track_orders_per_customer' );
This is totally untested, so use at your own risk. Also, you might want to look into changing the number of orders total in case of refunds/cancellations, etc, but this seems like the general gist.

Categories