3
votes

I'm having trouble with the default WooCommerce shipping class settings. We have a small webshop with 2 shipping costs. One for products that fit in the mailbox, and other that don't.

We would like to make a setting that if there are 2 products with mailbox shipping class, than the price becomes a package price.

Now on default WooCommerce only charges 1x the mailbox shipping class.

2

2 Answers

2
votes

First you will need to make your shipping settings as in the below screen, for "Flat rate" shipping method and only one shipping class named "Mailbox" (setting the desired amounts for "Mailbox" or No shipping class):

enter image description here

So some of your products will have the "Mailbox" shipping class and all others no shipping class. The products without shipping class (No shipping class) will be your "package.

The following code will remove the cart items shipping class, if there is more than one item with the "Mailbox" shipping class:

// Updating cart item price
add_action( 'woocommerce_before_calculate_totals', 'change_change_shipping_class', 30, 1 );
function change_change_shipping_class( $cart ) {
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) )
        return;

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

    // HERE define your shipping class SLUG
    $mailbox_shipping_class = 'mailbox';

    $mailbox_count = 0;

    // 1st cart item Loop: Counting "mailbox" shipping classes cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        // Set the new price
        if( $cart_item['data']->get_shipping_class() == $mailbox_shipping_class ) {
            $mailbox_count += $cart_item['quantity'];
        }
    }

    // If there is more than one item we continue
    if( $mailbox_count <= 1 )
        return; // Exit

    // 2nd cart item Loop: Reset the cart items with shipping class "mailbox"
    foreach ( $cart->get_cart() as $cart_item ) {
        if(  $cart_item['data']->get_shipping_class() == $mailbox_shipping_class ){
            $cart_item['data']->set_shipping_class_id('0');
        }
    }
}

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

0
votes

Thanks for the code, worked great!

I used another shipping class id, not the 0. Got the id by inspecting the code of the page where you can enter the rates. (It said name="woocommerce_flat_rate_class_cost_58", so the id is 58.) That's my "big parcel" class. This way, it gets exported to my mail/label plugin properly.