Niklas Buschner
Niklas Buschner

Reputation: 354

Charge local pickup costs per item quantity in WooCommerce

I calculate my flat rate shipping cost like this: x * [qty]

I also want to use this method for my local pickup methods but using the function like shown above, does not work.

How can I achieve a shipping cost calculation based on the item quantity?

WordPress: 4.8.4 / WooCommerce: 3.1.1

Link to the page: http://www.minimoto.me/

UPDATE:

After the first helpful answer, this is the code I'm using:

add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_shipping_class', 10, 2 );
function hide_shipping_method_based_on_shipping_class( $rates, $package )
{
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    ##  -----  1. Hiding shipping methods based on shipping class 92  -----  ##

    // HERE define your shipping class to find
    $class = 92;

    // HERE define the shipping methods you want to hide
    $method_key_ids = array('local_pickup:8');

    // Checking in cart items
    foreach( WC()->cart->get_cart() as $cart_item ){
        // If we find the shipping class
        if( $cart_item['data']->get_shipping_class_id() == $class ){
            foreach( $method_key_ids as $method_key_id ){
                unset($rates[$method_key_id]); // Remove the targeted methods
            }
            break; // Stop the loop
        }
    }

    ##  ----- 2. Hiding shipping methods based on shipping class 132  -----  ##

    // HERE define your shipping class to find
    $class = 132;

    // HERE define the shipping methods you want to hide
    $method_key_ids = array('local_pickup:2', 'local_pickup:3', 'local_pickup:4');

    // Checking in cart items
    foreach( WC()->cart->get_cart() as $cart_item ){
        // If we find the shipping class
        if( $cart_item['data']->get_shipping_class_id() == $class ){
            foreach( $method_key_ids as $method_key_id ){
                unset($rates[$method_key_id]); // Remove the targeted methods
            }
            break; // Stop the loop
        }
    }

    ##  -------  3. Charge local pickup costs per item quantity  -------  ##

    $cart_items_count = WC()->cart->get_cart_contents_count(); // Cart items count

    // Iterating through Shipping Methods
    foreach ( $rates as $rate_key => $rate ) {
        $method_id = $rate_values->method_id;
        $rate_id = $rate_values->id;

        // For "Local pickup" Shipping" Method only
        if ( 'local_pickup' === $method_id ) {
            if( ! empty( $rates[$rate_id]->cost && $rates[$rate_id]->cost > 0 ) ) {
                // Set the rate calculated cost based on cart items count
                $rates[$rate_id]->cost = number_format($rates[$rate_id]->cost * $cart_items_count, 2);
                // Taxes rate cost (if enabled)
                foreach ($rates[$rate_id]->taxes as $key => $tax){
                    if( $rates[$rate_id]->taxes[$key] > 0 ){ // set the new tax cost
                        $taxes[$key] = number_format( $rates[$rate_id]->taxes[$key] * $cart_items_count, 2 );
                        $has_taxes = true;
                    } else {
                        $has_taxes = false;
                    }
                }
                if( $has_taxes )
                    $rates[$rate_id]->taxes = $taxes;
            }
        }
    }

    return $rates;
}

Upvotes: 1

Views: 655

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253784

You can make this in your existing customized code from this answer, using the custom function hooked in woocommerce_package_rates action hook.

With the following code, Your local pickup shipping methods costs will be multiplied by the total cart items count:

add_filter( 'woocommerce_package_rates', 'customizing_shipping_methods', 10, 2 );
function customizing_shipping_methods( $rates, $package )
{
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    ##  -----  1. Hiding shipping methods based on shipping class  -----  ##

    // HERE define your shipping class to find
    $class = 92;

    // HERE define the shipping methods you want to hide
    $method_key_ids = array('flat_rate:7', 'local_pickup:3');

    // Checking in cart items
    foreach( WC()->cart->get_cart() as $cart_item ){
        // If we find the shipping class
        if( $cart_item['data']->get_shipping_class_id() == $class ){
            foreach( $method_key_ids as $method_key_id ){
                unset($rates[$method_key_id]); // Remove the targeted methods
            }
            break; // Stop the loop
        }
    }

    ##  -------  2. Charge local pickup costs per item quantity  -------  ##

    $cart_items_count = WC()->cart->get_cart_contents_count(); // Cart items count

    // Iterating through Shipping Methods
    foreach ( $rates as $rate_key => $rate_values ) {
        $method_id = $rate_values->method_id;
        $rate_id = $rate_values->id;

        // For "Local pickup" Shipping" Method only
        if ( 'local_pickup' === $method_id ) {
            if( ! empty( $rates[$rate_id]->cost && $rates[$rate_id]->cost > 0 ) ) {
                // Set the rate calculated cost based on cart items count
                $rates[$rate_id]->cost = number_format($rates[$rate_id]->cost * $cart_items_count, 2);
                // Taxes rate cost (if enabled)
                foreach ($rates[$rate_id]->taxes as $key => $tax){
                    if( $rates[$rate_id]->taxes[$key] > 0 ){ // set the new tax cost
                        $taxes[$key] = number_format( $rates[$rate_id]->taxes[$key] * $cart_items_count, 2 );
                        $has_taxes = true;
                    } else {
                        $has_taxes = false;
                    }
                }
                if( $has_taxes )
                    $rates[$rate_id]->taxes = $taxes;
            }
        }
    }

    return $rates;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works

Sometimes, you should may be need to refresh shipping methods going to shipping areas, then disable / save and re-enable / save your "flat rate" and "local pickup" shipping methods.

Upvotes: 1

Related Questions