2

In Woocommerce I am trying to add a shipping fee if a cart item has a specific shipping class assigned to the related product. I would like this shipping fee to be multiplied by the cart item quantity…

I have this working when a product is added to the cart and the quantity is increased and the additional shipping fee is increased also. However if I add another product with the same shipping class and increase the quantity the additional fee does not increase.

This is my code:

// Add additional fees based on shipping class
function woocommerce_fee_based_on_shipping_class( $cart_object ) {

    global $woocommerce;

    // Setup an array of shipping classes which correspond to those created in Woocommerce
    $shippingclass_dry_ice_array = array( 'dry-ice-shipping' );
    $dry_ice_shipping_fee = 70;

    // then we loop through the cart, checking the shipping classes
    foreach ( $cart_object->cart_contents as $key => $value ) {
        $shipping_class = get_the_terms( $value['product_id'], 'product_shipping_class' );
        $quantity = $value['quantity'];

        if ( isset( $shipping_class[0]->slug ) && in_array( $shipping_class[0]->slug, $shippingclass_dry_ice_array ) ) {
            $woocommerce->cart->add_fee( __('Dry Ice Shipping Fee', 'woocommerce'), $quantity * $dry_ice_shipping_fee ); // each of these adds the appropriate fee
        }
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'woocommerce_fee_based_on_shipping_class' ); // make it all happen when Woocommerce tallies up the fees

How can I make it work for additional cart items too?

starball
  • 20,030
  • 7
  • 43
  • 238

2 Answers2

3

Your code is a bit outdated and there is some mistakes. To add a fee based on product shipping class and cart item quantity use the following:

// Add a fee based on shipping class and cart item quantity
add_action( 'woocommerce_cart_calculate_fees', 'shipping_class_and_item_quantity_fee', 10, 1 ); 
function shipping_class_and_item_quantity_fee( $cart ) {

    ## -------------- YOUR SETTINGS BELOW ------------ ##
    $shipping_class = 'dry-ice-shipping'; // Targeted Shipping class slug
    $base_fee_rate  = 70; // Base rate for the fee
    ## ----------------------------------------------- ##

    $total_quantity = 0; // Initializing

    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item ) {
        // Get the instance of the WC_Product Object
        $product = $cart_item['data'];

        // Check for product shipping class
        if( $product->get_shipping_class() == $shipping_class ) {
            $total_quantity += $cart_item['quantity']; // Add item quantity
        }
    }

    if ( $total_quantity > 0 ) {
        $fee_text   = __('Dry Ice Shipping Fee', 'woocommerce');
        $fee_amount = $base_fee_rate * $total_quantity; // Calculate fee amount

        // Add the fee
        $cart->add_fee( $fee_text, $fee_amount );
    }
}

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • 1
    Perfect! thanks a lot, it works exactly how I wanted it to. – user3328399 Mar 05 '19 at 13:37
  • Would you know how or if it is possible to restrict the the shipping class to certain countries , the UK for example ? – user3328399 Mar 06 '19 at 15:28
  • The dry ice shipping fee should only be available to customers in the UK or Ireland , it's not available to other countries. I was thinking that it may be possible to unset the $shipping_class if the billing / shipping country is anything other than UK or Ireland. – user3328399 Mar 06 '19 at 15:58
  • I added the code ' if( in_array( WC()->customer->Get_shipping_country(), array( 'GB', 'IE' ) ) ) return; ' and it removes the dry ice shipping class for the UK & Ireland, however it makes it available for other countries. It should be the other way around. – user3328399 Mar 06 '19 at 16:32
  • Try instead the following line of code: `if( ! in_array( WC()->customer->Get_shipping_country(), array( 'GB', 'IE' ) ) ) return;` … It will work *(I forgot `!`)*. – LoicTheAztec Mar 06 '19 at 16:46
  • That worked, thank's a lot. I definitely owe you a coffee / beer :) – user3328399 Mar 06 '19 at 16:54
0

If there is one shipping class in cart there should be no fees, but if there is more than one shipping class, then should be additional 1 Eur handling fee and increase for every another shipping class.

Situation 1: Product with shipping class (Warehouse 1) added to cart = No extra fees

Situation 2: Product with shipping class (Warehouse 1) added to cart, Product with another shipping class (Warehouse 2) added to cart = 1x Handling fee added to cart Subtotals: Products 2x - 10 Eur Shipping - Free Handling fee 1x - 1Eur Total - 11 Eur

Situation 3: Product with shipping class (Warehouse 1) added to cart, Product with shipping class (Warehouse 2) added to cart, Product with shipping class (Warehouse 3) added to cart = 2x Handling fee added to cart Subtotals: Products 3x - 15 Eur Shipping - Free Handling fee 2x - 1Eur Total - 12 Eur