Reputation: 11
I have the code following placed in functions.php
function shipping_weight_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$extraFee = 0;
$total_weight = 0;
// Loop though each cart item
foreach ( $cart->get_cart() as $cart_item ) {
// Get product id
$product_id = $cart_item['product_id'];
// Get weight
$product_weight = $cart_item['data']->get_weight();
// NOT empty
if ( ! empty( $product_weight ) ) {
// Quantity
$product_quantity = $cart_item['quantity'];
// Add to total
$total_weight += $product_weight * $product_quantity;
}
}
if ( $total_weight > 10 ) {
$extraFee = 20;
}
}
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_fee', 10, 1 );
How can I get $extraFee from first code snippet to work in following code: I tried with global but it does not work. I believe the second code runs first but I am not sure.
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( $rate->method_id != 'free_shipping'){
// Set rate cost
$rates[$rate_key]->cost += $extraFee + 3;
}
}
return $rates;
}
Please help, thank You!
Upvotes: 1
Views: 1323
Reputation: 4100
If you don't want to add a fee to the cart you can avoid using the woocommerce_cart_calculate_fees
hook and create a single function with the woocommerce_package_rates
hook (combining the two functions):
// set custom shipping cost by weight
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
$extraFee = 0;
$total_weight = 0;
// Loop though each cart item
foreach ( WC()->cart->get_cart() as $cart_item ) {
// Get weight
$product_weight = $cart_item['data']->get_weight();
// NOT empty
if ( ! empty( $product_weight ) ) {
// Quantity
$product_quantity = $cart_item['quantity'];
// Add to total
$total_weight += $product_weight * $product_quantity;
}
}
if ( $total_weight > 10 ) {
$extraFee = 20;
}
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( $rate->method_id != 'free_shipping'){
// Set rate cost
$rates[$rate_key]->cost += $extraFee + 3;
}
}
return $rates;
}
The code has been tested and works. Add it to your active theme's functions.php.
Upvotes: 1
Reputation: 253773
You can use the WC_Cart
method get_cart_contents_weight()
to get the cart total weight instead simplifying the code.
This will work if cart is not split in multiple shipping packages (see the other code below).
The following code handle also the shipping taxes calculations:
add_filter( 'woocommerce_package_rates', 'additional_shipping_weight_costs', 10, 2 );
function additional_shipping_weight_costs( $rates, $package ) {
$extra_cost = (20 + 3); // Here define your extra shipping fee
$total_weight = WC()->cart->get_cart_contents_weight(); // Get total weight
if ( $total_weight > 10 ) {
// Loop through available shipping rates
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( 'free_shipping' !== $rate->method_id ){
$has_taxes = false; // Initializing
$taxes = array(); // Initializing
$initial_cost = $rate->cost;
$new_cost = $rate->cost + $extra_cost;
$rates[$rate_key]->cost = $new_cost;
// Loop through taxes array (change taxes rate cost if enabled)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $tax > 0 ){
// Get the tax rate conversion
$tax_rate = $tax / $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). Tested and works.
Don't forget to empty your cart to refresh shipping rates caches.
As cart items can be split into multiple shipping packages by some plugins or custom code, in that case, you will use the following code that handle also shipping taxes calculations:
add_filter( 'woocommerce_package_rates', 'additional_shipping_weight_costs', 10, 2 );
function additional_shipping_weight_costs( $rates, $package ) {
$extra_cost = (20 + 3); // Here define your extra shipping fee
$total_weight = 0; // Initializing
// Get cart items for the current shipping package (to calculate package weight)
foreach( $package['contents'] as $item ) {
$total_weight += floatval( $item['data']->get_weight() ) * $item['quantity'];
}
if ( $total_weight > 10 ) {
// Loop through available shipping rates
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( 'free_shipping' !== $rate->method_id ){
$has_taxes = false; // Initializing
$taxes = array(); // Initializing
$initial_cost = $rate->cost;
$new_cost = $initial_cost + $extra_cost;
$rates[$rate_key]->cost = $new_cost; // Set new rate cost
// Loop through taxes array (change taxes rate cost if enabled)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $tax > 0 ){
// Get the tax rate conversion
$tax_rate = $tax / $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). Tested and works.
Don't forget to empty your cart to refresh shipping rates caches.
Related: Filter "woocommerce_cart_contents_weight" not applied for shipping weight
Upvotes: 2