'WooCommerce how to perform conditional checks for custom categories
I have a Woocommerce store and I'm trying to add prefixes to the order number based on if the order contains a product within one of two different categories.
The two categories are Customs and Refurbished.
This code works perfectly if the order only contains a Custom or a Refurbished product, but the problem occurs when an order contains both a Custom and Refurbished product. This code will just apply the prefix of CPC- or REF- depending on whatever item is first in the order.
I want to make it so that if an order contains both of these categories, that the system defaults to adding the Custom prefix of CPC- but I can't figure out how to do that.
Below is my code, look for the 💩 to find my failed attempt to fix this
add_filter( 'woocommerce_order_number', 'change_woocommerce_order_number' );
function change_woocommerce_order_number( $order_id ) {
// 1. Get order object
$order = wc_get_order( $order_id );
// 2. Initialize $cat_in_order variable
$cat_in_order = '';
// 3. Get order items and loop through them...
// ... if product in category, edit $cat_in_order
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
if ( has_term( 'refurbished', 'product_cat', $product_id )) {
$cat_in_order = 'refurbished';
break;
} elseif ( has_term( 'customs', 'product_cat', $product_id )) {
$cat_in_order = 'customs';
break;
//
// 💩 Here's my attempt to fix this, but it's not working 💩
//
} elseif ( has_term( 'customs', 'product_cat', $product_id ) && has_term( 'refurbished', 'product_cat', $product_id )) {
$cat_in_order = 'customs';
break;
}
}
// 4. Add Order Prefix if in Customs Category
if ( $cat_in_order == 'refurbished' ) {
$prefix = 'REF-';
$new_order_id = $prefix . $order_id;
return $new_order_id;
} elseif ( $cat_in_order == 'customs' ) {
$prefix = 'CPC-';
$new_order_id = $prefix . $order_id;
return $new_order_id;
} else {
return $order_id;
}
}
Solution 1:[1]
Starting from answer of Ruvee there is some tuning we can perform.
The problem is implicity you set a hierarchy in your choice.
So if Custom attribute is set this has precedence.
in this case we can simply the code in this way.
foreach ($items as $item) {
$product_id = $item->get_product_id();
if ( has_term('customs', 'product_cat', $product_id) ){
$cat_in_order = 'customs';
} elseif ( has_term('refurbished', 'product_cat', $product_id) ) {
$cat_in_order = 'refurbished';
} else {
// Manage the exception!
}
}
So if Custom is true elseif is not processed and we don't need to set other conditions.
However, pay attantion on the break usage, is not needed in if / elseif statement, and it's wrong.
Solution 2:[2]
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
if ( has_term( 'customs', 'product_cat', $product_id ) && has_term( 'refurbished', 'product_cat', $product_id )) {
$cat_in_order = 'customs';
}
elseif ( has_term( 'refurbished', 'product_cat', $product_id )) {
$cat_in_order = 'refurbished';
} elseif ( has_term( 'customs', 'product_cat', $product_id )) {
$cat_in_order = 'customs';
;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Domenico Lorusso |
| Solution 2 | Maulik patel |
