问题
I want to add a fee in my woocommerce store for orders under a specific amount (value, not quantity).
I am using "WooCommerce dynamic minimum order amount based fee" answer code that works perfectly.
Now I am trying to change this functionand to apply it only to items from a specific product category. Basically, I have to sum the value of all the products in cart that matches the specific category and use this value for fee calculation.
How can I reach this goal?
回答1:
The following revisited code will handle specific defined product categories. You will have to define:
- Your specific product categories in the 1st function.
- The minimal order amount in the 2nd and 3rd functions.
The code:
// Get the cart items subtotal amount from specific product categories
function get_specific_cart_items_total( $cart ) {
$categories = array('t-shirts'); // <=== Define your product categories
$items_amount = 0; // Initializing
// Loop through cart items
foreach( $cart->get_cart() as $item ) {
if( has_term( $categories, 'product_cat', $item['product_id'] ) ) {
$items_amount += $item['line_subtotal'];
}
}
return $items_amount;
}
// Add a custom fee (displaying a notice in cart page)
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_cart_calculate_fees' ) >= 2 )
return;
$min_price = 200; // The minimal cart amount
$current_price = get_specific_cart_items_total( $cart );
$custom_fee = $min_price - $current_price;
if ( $custom_fee > 0 ) {
$cart->add_fee( __('Minimum Order Adjustment'), $custom_fee, true );
// NOTICE ONLY IN CART PAGE
if( is_cart() ){
wc_print_notice( get_custom_fee_message( $min_price, $current_price ), 'error' );
}
}
}
// Displaying the notice on checkout page
add_action( 'woocommerce_before_checkout_form', 'custom_surcharge_message', 10 );
function custom_surcharge_message( ) {
$min_price = 200; // The minimal cart amount
$cart = WC()->cart;
$current_price = get_specific_cart_items_total( $cart );
$custom_fee = $min_price - $current_price;
// NOTICE ONLY IN CHECKOUT PAGE
if ( $custom_fee > 0 ) {
wc_print_notice( get_custom_fee_message( $min_price, $current_price ), 'error' );
}
}
// The fee notice message
function get_custom_fee_message( $min_price, $current_price ) {
return sprintf(
__('We have a minimum %s per order from specific categories. As your current order is only %s, an additional fee will be applied.', 'woocommerce'),
wc_price( $min_price ),
wc_price( $current_price )
);
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Option: To handle parent product categories too, add the following additional function:
// Custom conditional function (like has_term()) that handle parent product categories too
function has_product_categories( $categories, $product_id = 0 ) {
// Initializing
$parent_term_ids = $categories_ids = array();
$taxonomy = 'product_cat';
if( is_string( $categories ) ) {
$categories = (array) $categories;
}
$product_id = $product_id > 0 ? $product_id : get_the_id();
// Convert categories term names and slugs to categories term ids
foreach ( $categories as $category ){
if( is_numeric( $category ) ) {
$categories_ids[] = (int) $category;
} elseif ( term_exists( sanitize_title( $category ), $taxonomy ) ) {
$categories_ids[] = get_term_by( 'slug', sanitize_title( $category ), $taxonomy )->term_id;
}
}
// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
$parent_term_ids[] = $term->term_id; // (and the child)
} else {
$parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
}
}
return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
}
And replace in the first function this line:
if( has_term( $categories, 'product_cat', $item['product_id'] ) ) {
by this:
if( has_product_categories( $categories, $item['product_id'] ) ) {
来源:https://stackoverflow.com/questions/56231909/woocommerce-minimum-order-fee-for-products-in-specific-category