0
votes

I'm trying to increase shipping cost based on number of categories in cart (count). So far I have this:

add_filter( 'woocommerce_package_rates', 'vh_wc_shipping_costs', 20 );

function vh_wc_shipping_costs( $rates ) {
    $increase_cost = 50;
    $cat_ids       = array();
    $count         = 0;

    foreach ( wc()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $cat_ids = array_merge(
            $cat_ids,
            (array) $cart_item['data']->get_category_ids()
        );
        $count   = count( $cat_ids );
    }

    $i=0;

    if ( $count >= 1 ) {
        foreach ( $rates as $rate_key => $rate ) {
            $i++; $i <= $count;

            // Excluding free shipping methods
            if ( 'free_shipping' !== $rate->method_id ) {
                // Get old cost
                $old_cost = $rates[ $rate_key ]->cost;

                // Set rate cost
                $rates[ $rate_key ]->cost = $old_cost + $increase_cost;
            }
        }
    }

    return $rates;
}

But it doesn't increment the shipping cost for every extra category for some reason. Also, I would like to add a note to the extra cost. Any Suggestion is appreciated.

1
"Needs more focus: This question currently includes multiple questions in one. It should focus on one problem only". Note that the rule on StackOverFlow is one question at the time.LoicTheAztec

1 Answers

2
votes

As the rule on StackOverFlow is one question at the time, I will only answer the first question related to your code.

The following code will add an extra shipping cost for each additional product category found in cart (so not for the first one):

add_filter( 'woocommerce_package_rates', 'filter_shipping_rates_costs', 10, 2 );
function filter_shipping_rates_costs( $rates, $package ) {
    $step_cost = 50;
    $term_ids  = array();

    // Loop through cart items for the current shipping package
    foreach( $package['contents'] as $cart_item ){
        $term_ids = array_merge(
            $term_ids,
            (array) $cart_item['data']->get_category_ids()
        );
    }

    $terms_count = count( $term_ids );

    // Loop through shipping rates
    foreach ( $rates as $rate_key => $rate ) {
        // Excluding free shipping methods
        if ( 'free_shipping' !== $rate->method_id && $terms_count > 1 ) {
            // Set rate cost
            $rates[$rate_key]->cost = $rate->cost + ($step_cost * ($terms_count - 1));
        }
    }

    return $rates;
}

Now if you want to add an extra shipping cost for each category found in cart, use the following:

add_filter( 'woocommerce_package_rates', 'filter_shipping_rates_costs', 10, 2 );
function filter_shipping_rates_costs( $rates, $package ) {
    $step_cost = 50;
    $term_ids  = array();

    // Loop through cart items for the current shipping package
    foreach( $package['contents'] as $cart_item ){
        $term_ids = array_merge(
            $term_ids,
            (array) $cart_item['data']->get_category_ids()
        );
    }

    $terms_count = count( $term_ids );

    // Loop through shipping rates
    foreach ( $rates as $rate_key => $rate ) {
        // Excluding free shipping methods
        if ( 'free_shipping' !== $rate->method_id && $terms_count > 0 ) {
            // Set rate cost
            $rates[$rate_key]->cost = $rate->cost + ($step_cost * $terms_count);
        }
    }

    return $rates;
}

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

Refresh the shipping caches:

  1. This code is already saved on your functions.php file.
  2. In a shipping zone settings, disable / save any shipping method, then enable back / save.

    You are done and you can test it.