Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add an additional cost to flat rate shipping each 3 items in Woocommerce

I'm running a woocommerce shop and using a Flat Rate shipping $15. I have written a formula to add $1.25 for each additional item.

13.50 + ( 1.25 * [qty])

Sipping "flat rate settings | $1.25 for Additional Each Item:

$1.25 for Additional Each Item

But I want to add this cost $1.25 for every 3 items. I mean 3, 6, 9, 12 and so on...

Can anyone tell me how to do this? Any help is appreciated.

like image 990
Muhammad Irfan Avatar asked Jul 04 '18 03:07

Muhammad Irfan


People also ask

How do I set different shipping options in WooCommerce?

Go to: WooCommerce > Settings > Shipping > Shipping Zones. Hover over Zone Name, and the option to Edit and Delete appear. Select Edit, and a screen appears so you can change the name, regions or shipping methods. Save changes.


1 Answers

Updated (2021)

The following code will add an additional cost to flat rate shipping method each 3 items (3, 6, 9 …).

You will need to change your shipping cost with a simple initial cost instead of your formula.

You may have to "Enable debug mode" in general shipping settings under "Shipping options" tab, to disable temporarily shipping caches.

The code (where you will set your additional shipping cost):

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

    // HERE set your additional shipping cost
    $additional_cost = 1.25;
    $items_count     = 0; // Initializing
    $each_items      = 3; // Number of items (for additional cost)

    // Loop through cart items for the current shipping package        
    foreach( $package['contents'] as $cart_item ) {
        $items_count = += $cart_item['quantity']; // Count cart items for current shipping package
    }

    if ( $items_count >= $each_items ) {
        // Loop through the shipping taxes array
        foreach ( $rates as $rate_key => $rate ){
            // Targetting "flat rate"
            if( 'flat_rate' === $rate->method_id ){
                $initial_cost = $new_cost = $rate->cost;
                $has_taxes    = false; // Initializing
                $taxes        = array(); // Initializing
                
                // Adding to cost the additional cost each 3 items (3, 6, 9 …)
                for($i = 0; $i <= $items_count; $i+ = $each_items){
                    $new_cost += $additional_cost;
                }
                $rates[$rate_key]->cost = $new_cost; // Set the new cost
    
                // Taxes rate cost (if any) - Loop through taxes array (as they can be many)
                foreach ($rate->taxes as $key => $tax){
                    if( $tax > 0 ){
                        // Get the initial tax cost
                        $initial_tax_cost = $new_tax_cost = $tax;
                        // Get the tax rate conversion
                        $tax_rate    = $initial_tax_cost / $initial_cost;
                        // Set the new tax cost
                        $taxes[$key] = $new_cost * $tax_rate;
                        $has_taxes   = true; // Enabling tax changes
                    }
                }
                // set array of shipping tax cost
                if( $has_taxes ) {
                    $rates[$rate_key]->taxes = $taxes; 
                }
            }
        }
    }
    return $rates;
}

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

Don't forget to disable "Enable debug mode" option in shipping settings.


Answer based on your 2nd comment:

you will replace this block:

// Adding to cost the additional cost each 3 items (3, 6, 9 …)
for($i = 0; $i <= $items_count; $i += $each_items){
    $new_cost += $additional_cost;
}

by the following:

// Adding to cost an additional fixed cost for the 2nd item
if($items_count >= 2){
    $new_cost += 6.21; 
}

// Adding to cost the additional cost each 3 items (3, 6, 9 …)
for($i = 0; $i <= $items_count; $i += $each_items){
    $new_cost += $additional_cost;
}
like image 63
LoicTheAztec Avatar answered Oct 05 '22 13:10

LoicTheAztec