yosober
yosober

Reputation: 355

Fees based from WooCommerce product categories cart item count

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.

Upvotes: 1

Views: 1523

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253784

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.

Upvotes: 1

Related Questions