skip to Main Content

Good evening.
I wrote some code to alter the total weight of some specific articles in my cart (due to a specific request of the courier). Before you ask… no, I cannot modify the single article weight, because I have to calculate a special weight for packaging. Yes, it’s a long story,

My code looks like that (simplified version):

function set_my_weight($weight) {
  global $woocommerce;
  $cart_items = $woocommerce->cart->get_cart(); 
  $addedWeight = 0;

  echo "prev: ". $weight;
  foreach($cart_items as $prod => $values):
     if(conditions):
       $addedWeight += 1.5;
     endif;
  endforeach;

  $weight += $addedWeight;
  echo "final: ". $weight;

  return $weight;
}
add_filter('woocommerce_cart_contents_weight', 'set_my_weight',10,1);

When I echo the value calling
echo WC()->cart->cart_contents_weight; all seems working fine, but for some reason the shipping costs do not change.
I’m using “WooCommerce Weight Based Shipping” plugin to manage my shipping costs.

Why the new weight is ignored by the plugin?

Thanks

3

Answers


  1. As WooCommerce Weight Based Shipping is a third party plugin, there is different ways to calculate cost changes based on cart weight.

    Here below are 2 ways to alter the cart weight.

    1) Alter cart contents total weight:

    add_filter( 'woocommerce_cart_contents_weight', 'filter_wc_cart_contents_weight', 10000 );
    function filter_wc_cart_contents_weight( $weight ) {
        $condition    = true; // Only for testing
        $extra_weight = 1.5;
    
        // Loop through cart items
        foreach(WC()->cart->get_cart() as $cart_item ) {
            $quantity = $cart_item['quantity']; // If needed
    
            if( $condition ) {
                $weight += $extra_weight;
            }
        }
        return $weight;
    }
    
    // For testing: display the total weight after order total in cart page (Ajax updated)
    add_action( 'woocommerce_cart_totals_after_order_total', 'display_wc_cart_total_weight_after_order_total' );
    function display_wc_cart_total_weight_after_order_total() {
        ?>
        <tr class="order-total">
            <th><?php esc_html_e( 'Total weight', 'woocommerce' ); ?></th>
            <td data-title="<?php esc_attr_e( 'Total weight', 'woocommerce' ); ?>"><?php echo wc_format_weight( WC()->cart->get_cart_contents_weight() ); ?></td>
        </tr>
        <?php
    }
    

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


    2) Alter cart items weight:

    add_action( 'woocommerce_before_calculate_totals', 'conditionally_change_tax_class', 10000 );
    function conditionally_change_tax_class( $cart ){
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Required since Woocommerce version 3.2 for cart items properties changes
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        $condition    = true; // Only for testing
        $extra_weight = 1.5;
    
        // Looo through our specific cart item keys
        foreach ( $cart->get_cart() as $cart_item ) {
            // get product weight
            $weight = (float) $cart_item['data']->get_weight();
    
            // Set the new product weight
            $cart_item['data']->set_weight( $weight + ( $extra_weight / $cart_item['quantity'] ) );
        }
    }
    
    // For testing display the total weight after order total
    add_action( 'woocommerce_cart_totals_after_order_total', 'display_wc_cart_total_weight_after_order_total' );
    function display_wc_cart_total_weight_after_order_total() {
        ?>
        <tr class="order-total">
            <th><?php esc_html_e( 'Total weight', 'woocommerce' ); ?></th>
            <td data-title="<?php esc_attr_e( 'Total weight', 'woocommerce' ); ?>"><?php echo wc_format_weight( WC()->cart->get_cart_contents_weight() ); ?></td>
        </tr>
        <?php
    }
    

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


    Now if WooCommerce Weight Based Shipping plugin get the weight from each product, you will be not able to alter cart weight, so shipping costs.

    Login or Signup to reply.
  2. If you are using this WooCommerce Weight Based Shipping plugin,

    @LoicTheAztec answer’s could work if you change the cart data early before
    WC()->cart->calculate_shipping() which is using the hook woocommerce_checkout_update_order_review.

    add_action( 'woocommerce_checkout_update_order_review', 'conditionally_change_tax_class', 10000 );
    

    Source: woocommerce/includes/class-wc-ajax.php

    Login or Signup to reply.
  3. The filter woocommerce_cart_contents_weight is not usable since get_cart_contents_weigh is not used to set the shipping fee. A solution is to modify the weight of each product of the cart.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search