Based on Add an additional cost to flat rate shipping each 3 items in Woocommerce answer code, I have made some changes to add an additional cost to flat are shipping method each 2 items (instead of each 3 items) and only when there are exclusively items from a specific category (here “T-Shirts” category).
Here’s my code attempt:
// add X amount to shipping for every 2 items added to the cart (flat rate only) add_filter('woocommerce_package_rates', 'shipping_additional_cost_each_three_items', 100, 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 = 8.40; $items_count = WC()->cart->get_cart_contents_count(); // Define/replace here your correct category slug (!) $product_category = 't-shirts'; $prod_cat = false; // Going through each item in cart to see if there is anyone of your category foreach ( WC()->cart->get_cart() as $cart_item ) { $product_id = $cart_item['product_id']; if ( has_term( $product_category, 'product_cat', $product_id ) ){ $prod_cat = true; } } // Loop through the shipping taxes array foreach ( $rates as $rate_key => $rate ){ $has_taxes = false; // Targetting "flat rate" if( 'flat_rate' === $rate->method_id ){ // Get the initial cost $initial_cost = $new_cost = $rates[$rate_key]->cost; // Adding the additional cost if product in T-Shirt category after every 2 items (3, 6, 9 …) if ( $prod_cat ) { for($i = 0; $i <= $items_count; $i+=3){ $new_cost += $additional_cost; } } // Set the new cost $rates[$rate_key]->cost = $new_cost; // Taxes rate cost (if enabled) $taxes = []; // Loop through the shipping taxes array (as they can be many) foreach ($rates[$rate_key]->taxes as $key => $tax){ if( $rates[$rate_key]->taxes[$key] > 0 ){ // Get the initial tax cost $initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key]; // 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 } } } if( $has_taxes ) $rates[$rate_key]->taxes = $taxes; return $rates; } }
For “Flat rate” chosen shipping method, the code works just fine when items from “t-shirts” category are in the cart. But if there is an item that doesn’t belongs to “t-shirt” category, the rate just disappears and shows the title with no amount.
Can someone tell me where I have to place the condition ‘if category is X’, to make that code functional?
Advertisement
Answer
There are some mistakes in your code (like return $rates;
that should need to be just before last closing bracket). Try the following revisited code instead:
add_filter('woocommerce_package_rates', 'shipping_additional_cost_each_three_items', 100, 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 = 8.40; $each_items = 2; // Number of items (for additional cost) // Her set your category(ies) (can be term Ids slugs or names) $product_categories = array('t-shirts'); $items_cat_count = 0; // Initializing // Loop through cart items for the current shipping package foreach( $package['contents'] as $cart_item ) { if ( ! has_term( $product_categories, 'product_cat', $cart_item['product_id'] ) ){ $items_cat_count += $cart_item['quantity']; // Count items from defined category } } if ( $items_cat_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; // Get the initial cost $has_taxes = false; // Initializing $taxes = array(); // Initializing // Adding to cost the additional cost each 2 items (2, 4, 6 …) for($i = 0; $i <= $items_cat_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 in the array $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 functions.php file of the active child theme (or active theme). It should works.
Don’t forget to empty your cart to refresh shipping cached data.