phpwordpresswoocommerceproductfee

Apply fee based on product category and product length in WooCommerce


I'm trying to apply a fee based on the product category and product length.

If the product belongs to a certain category and the length is less than 30m I want to charge a cut price fee per product (cost to cut roll of flooring).

I have a function working that adds the cut price to a certain category but I can't seem to figure out how to make it conditional so it only adds the fee if the item is less than 30m long

Please see two versions I have tried below:

Function 1: The code below is working without the length condition so adds fee to each item in the cart with a certain category

// Add cut price to category flotex
function woo_add_cart_fee() {

$category_ID = '83'; // Flotex Category is 83
global $woocommerce;
$cpfee = 0.00; // initialize special fee

//Getting Cart Contents. 
$cart = $woocommerce->cart->get_cart();

//Calculating Quantity in cart
foreach($cart as $cart_val => $cid){
   $qty += $cid['quantity']; 
}

foreach ($woocommerce->cart->cart_contents as $key => $values ) {
    // Get the terms, i.e. category list using the ID of the product
    $terms = get_the_terms( $values['product_id'], 'product_cat' );
        // Because a product can have multiple categories, we need to iterate through the list of the products category for a match
        foreach ($terms as $term) {
            // 83 is the ID of the category for which we want to remove the payment gateway
            if($term->term_id == $category_ID){
                $cutprice = 30;
            }
            $cpfee = $qty * $cutprice;
        }
        $woocommerce->cart->add_fee('Cut Price', $cpfee, $taxable = true, $tax_class = 'standard');
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );

?>

Function 2: The code below is an attempt at adding the conditional length rule but it's not working. It always returns either 0 or charges 30 for every item even if the length is 30

// Add cut price to category flotex
function woo_add_cart_fee() {

    $category_ID = '83'; // Flotex Category is 83
    global $woocommerce;
    $cpfee = 0.00; // initialize special fee
    $qty = 0;
    $cutpricesmall = 0;

    //Getting Cart Contents. 
    $cart = $woocommerce->cart->get_cart();

    //Calculating Quantity in cart
    foreach($cart as $cart_val => $cid){
       $qty += $cid['quantity']; 
    }

    foreach ($woocommerce->cart->cart_contents as $key => $values ) {

        $product = $values['data'];
        $length = $product->get_length();

        // Get the terms, i.e. category list using the ID of the product
        $terms = get_the_terms( $values['product_id'], 'product_cat' );
        
        if ( $length < 29 ) {
            // Because a product can have multiple categories, we need to iterate through the list of the products category for a match
            foreach ($terms as $term) {
                
                // 83 is the ID of the category for which we want to remove the payment gateway
                if($term->term_id == $category_ID){
                    
                        $cutprice = 30;
                }
            }

        } elseif ( $length > 29 ){
            foreach ($terms as $term) {
            
                // 83 is the ID of the category for which we want to remove the payment gateway
                if($term->term_id == $category_ID){
                    
                    $cutpricesmall = 0;
                }
            }
        }
        $cpfee = $qty * ($cutprice + $cutpricesmall);
        $woocommerce->cart->add_fee('Cut Price', $cpfee, $taxable = true, $tax_class = 'standard');
    
    }
    
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );

Any advice with this would be really appreciated.


Solution

  • Your code contains some mistakes or can be optimized:

    So you get:

    function action_woocommerce_cart_calculate_fees( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
        
        // Specific categories: the term name/term_id/slug. Several could be added, separated by a comma
        $categories = array( 83, 'categorie-1' );
    
        // Settings
        $cut_price = 30;
        $length = 30;
    
        // Initialize
        $cp_fee = 0;
         
        // Gets cart contents
        foreach ( $cart->get_cart_contents() as $cart_item ) {
            // Has certain category     
            if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ) {
                // Get length
                $product_length = $cart_item['data']->get_length();
    
                // NOT empty and less than
                if ( ! empty ( $product_length ) && $product_length < $length ) {
                    // Get quantity
                    $quantity = $cart_item['quantity'];
                
                    // Addition to the total
                    $cp_fee += $cut_price * $quantity;
                }
            }
        }
    
        // Greater than
        if ( $cp_fee > 0 ) {
            // Add fee
            $cart->add_fee( __( 'Cut Price', 'woocommerce' ), $cp_fee, true );
        }
    }
    add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
    

    Note: if the product quantity per product should not be taken into account

    Replace:

    // NOT empty and less than
    if ( ! empty ( $product_length ) && $product_length < $length ) {
        // Get quantity
        $quantity = $cart_item['quantity'];
    
        // Addition to the total
        $cp_fee += $cut_price * $quantity;
    }
    

    With:

    // NOT empty and less than
    if ( ! empty ( $product_length ) && $product_length < $length ) {    
        // Addition to the total
        $cp_fee += $cut_price;
    }