1
votes

Based on "Minimum cart item quantity for a specific product category in WooCommerce" and "Additional price based on cart item count in WooCommerce"

I am trying to count the products from specific product categories in checkout page, i just need a code that count the products from their category like in picture and if 2 products from 'headphone' category was in the cart then add 2 $ to total price

This image will explain everything:

enter image description here

Here is my code attempt:

add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fee', 10, 1 );
function custom_packing_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_cart_calculate_fees' ) >= 2 )
        return;

    $count = $cart->get_terms('')

    if ( $count->count >= 9 ){
        $fee = 15;
    }
    elseif( $count->count >= 6 && $count < 9 ){
        $fee = 14;
    }
    elseif( $count>count >= 4 && $count < 6 ){
        $fee = 13;
    }

    if ( isset($fee) && $fee > 0 ) {
        $label = sprintf( __('Box fee (%d items)'), $count);
        $cart->add_fee( $label, $fee, false );
    }

But it doesn't work.

1
When you say "And I have some rule like user can’t just buy 1 product from ‘consoles’ category it has to be 3 products", it's not understandable. Also 1 product from ‘headphones’ and 5 product from ‘headphones’ add both $2 (the same amount). Try to reword your question and to make it clear.LoicTheAztec
im sorry forget about that part i just need a code that count the products from their category like in picture and if 2 products from 'headphone' category was in the cart then add 2 $ to total priceyosober
Anyways, please first update/reword your question to make it clear for everybody. StackOverFlow questions have to be clear and understandable as Questions and answers are useful for others.LoicTheAztec
@LoicTheAztec sir i did it can you please answer my question?yosober

1 Answers

1
votes

Based on your last question code, here is the way to count items from different product categories. As you will see, the code is compact, optimized and more efficient.

Also you need to understand how hooks work when using:

The 2 last arguments are optional… By default the priority is 10 and the arguments count is:

  • 0 for an action hook.
  • 1 for a filter hook.

In a filter hook, the first function argument (variable) is always returned at the end of the function.


There are multiple possibilities:

1) Adding multiple fees for each product category count (item quantity count):

add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fees' );
function custom_packing_fees( $cart ) {
    if ( is_admin() && !defined('DOING_AJAX') )
        return;

    if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
        return;

    // Initializing data (settings)
    $data = [
        ['name' => __('Cupcake'),   'threshold' => 4,   'fee' => 15,    'count' => 0],
        ['name' => __('Cake'),      'threshold' => 3,   'fee' => 11,    'count' => 0],
        ['name' => __('Macaron'),   'threshold' => 6,   'fee' => 12,    'count' => 0],
    ];

    $fee_text   = __('"%s" box fee (%d items)');

    // Loop through cart items (counting product categories)
    foreach ( $cart->get_cart() as $item ) {
        // Loop through product categories
        foreach ( $data as $key => $values ) {
            if ( has_term( $values['name'], 'product_cat', $item['product_id'] ) ) {
                // Increase the product category count (based on quantity)
                $data[$key]['count'] += (int) $item['quantity'];
            }
        }
    }

    // Loop through product categories counts
    foreach ( $data as $key => $values ) {
        // Add a fee for each product category (when the count threshold value is reached)
        if( $values['count'] >= $values['threshold'] ) {
            $cart->add_fee( sprintf( $fee_text, $values['name'], $values['count'] ), $values['fee'], false );
        }
    }
}

2) Adding multiple fees for each product category count (cart item count, not quantity):

add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fees' );
function custom_packing_fees( $cart ) {
    if ( is_admin() && !defined('DOING_AJAX') )
        return;

    if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
        return;

    // Initializing data (settings)
    $data = [
        ['name' => __('Cupcake'),   'threshold' => 4,   'fee' => 15,    'count' => 0],
        ['name' => __('Cake'),      'threshold' => 3,   'fee' => 11,    'count' => 0],
        ['name' => __('Macaron'),   'threshold' => 6,   'fee' => 12,    'count' => 0],
    ];

    $fee_text   = __('"%s" box fee (%d items)');

    // Loop through cart items (counting product categories)
    foreach ( $cart->get_cart() as $item ) {
        // Loop through product categories
        foreach ( $data as $key => $values ) {
            if ( has_term( $values['name'], 'product_cat', $item['product_id'] ) ) {
                // Increase the product category count (based on cart item count)
                $data[$key]['count'] += 1;
            }
        }
    }

    // Loop through product categories counts
    foreach ( $data as $key => $values ) {
        // Add a fee for each product category (when the count threshold value is reached)
        if( $values['count'] >= $values['threshold'] ) {
            $cart->add_fee( sprintf( $fee_text, $values['name'], $values['count'] ), $values['fee'], false );
        }
    }
}

3) Adding a unique fee for all product categories count (item quantity count):

add_action( 'woocommerce_cart_calculate_fees', 'custom_packing_fees' );
function custom_packing_fees( $cart ) {
    if ( is_admin() && !defined('DOING_AJAX') )
        return;

    if ( did_action('woocommerce_cart_calculate_fees') >= 2 )
        return;

    // Initializing data (settings)
    $data = [
        ['name' => __('Cupcake'),   'threshold' => 4,   'fee' => 15,    'count' => 0],
        ['name' => __('Cake'),      'threshold' => 3,   'fee' => 11,    'count' => 0],
        ['name' => __('Macaron'),   'threshold' => 6,   'fee' => 12,    'count' => 0],
    ];

    $fee_text   = __('Box fee (%d items)');
    $fee_amount = 0;
    $total_count = 0;

    // Loop through cart items (counting product categories)
    foreach ( $cart->get_cart() as $item ) {
        // Loop through product categories
        foreach ( $data as $key => $values ) {
            if ( has_term( $values['name'], 'product_cat', $item['product_id'] ) ) {
                // Increase the product category count (based on quantity)
                $data[$key]['count'] += (int) $item['quantity'];
            }
        }
    }

    // Loop through product categories counts
    foreach ( $data as $key => $values ) {
        // Calculate the fee amount for all product categories (when the count threshold value is reached)
        if( $values['count'] >= $values['threshold'] ) {
            $fee_amount  += $values['fee'];
            $total_count += $values['count'];
        }
    }

    // The unique fee merged
    if ( $fee_amount > 0 ) {
        $cart->add_fee( sprintf( $fee_text, $total_count ), $fee_amount, false );
    }
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.