Search code examples
phpwordpresswoocommerceshipping-methodproduct-quantity

Woocommerce shipping cost based on item quantity for specific shipping class


I posted this code a few hours ago. I managed to get through one of the issues, but i have only one question now. This code works well but I need to multiply the cost for every single item using an specific shipping class and then add it to the regular shipping cost.

Example if I have 5 products in the cart:

  • 2 of them use shipping-class-1 ($70 extra shipping cost for product)
  • 3 of them use shipping-class-2 ($50 extra shipping cost for product)

So if (for example) the regular shipping costs $120 then the shipping should be ($120 + $290) = $410

add_filter( 'woocommerce_package_rates', 'ph_add_extra_cost_based_on_shipping_class', 10, 2);
if( ! function_exists('ph_add_extra_cost_based_on_shipping_class') ) {
    function ph_add_extra_cost_based_on_shipping_class( $shipping_rates, $package ){

        $handling_fee_based_on_shipping_class = array(
            array(
                'shipping_classes'  =>  array( 'shipping-class-1'),         // Shipping Class slug array
                'adjustment'        => 70,                                  // Adjustment
            ),
            array(
                'shipping_classes'  =>  array( 'shipping-class-2' ),
                'adjustment'        =>  50,
            ),
        );

        $shipping_method_ids = array( 'cologistics-shipping' );     // Shipping methods on which adjustment has to be applied

        $adjustment = null;
        foreach( $package['contents'] as  $line_item ) {
            $line_item_shipping_class = $line_item['data']->get_shipping_class();
            if( ! empty($line_item_shipping_class) ) {
                foreach( $handling_fee_based_on_shipping_class as $adjustment_data ) {
                    if( in_array( $line_item_shipping_class, $adjustment_data['shipping_classes']) ) {
                        $adjustment = ( $adjustment_data['adjustment'] > $adjustment ) ? $adjustment_data['adjustment'] : $adjustment;
                    }
                }
            }
        }

        if( ! empty($adjustment) ) {
            foreach( $shipping_rates as $shipping_rate ) {
                $shipping_method_id = $shipping_rate->get_method_id();
                if( in_array($shipping_method_id, $shipping_method_ids) ) {
                    $shipping_rate->set_cost( (float) $shipping_rate->get_cost() + $adjustment );
                }
            }
        }

        return $shipping_rates;
    }
}

I will really appreciate your help.

Thanks in advance!


Solution

  • This doesn't require any code normally… You should set your shipping method as follow (so first remove your code and save):

    enter image description here

    1) So you will keep 120 as global cost in your shipping method.

    2) Then for each related desired shipping class you will add in the corresponding field:

    • [qty]*70 for shipping-class-1
    • [qty]*50 for shipping-class-2
    • Calculation type: Per class: Charge shipping for each shipping class individually

    This will work and will add to the cost an amount by chipping class based on cart item quantity.


    For a custom shipping method based on your code, you should use the following to handle item quantity:

    add_filter( 'woocommerce_package_rates', 'ph_add_extra_cost_based_on_shipping_class', 10, 2);
    if( ! function_exists('ph_add_extra_cost_based_on_shipping_class') ) {
        function ph_add_extra_cost_based_on_shipping_class( $shipping_rates, $package ){
    
            $handling_fee_based_on_shipping_class = array(
                array(
                    'shipping_classes'  =>  array( 'shipping-class-1'),         // Shipping Class slug array
                    'adjustment'        => 70,                                  // Adjustment
                ),
                array(
                    'shipping_classes'  =>  array( 'shipping-class-2' ),
                    'adjustment'        =>  50,
                ),
            );
    
            $shipping_method_ids = array( 'cologistics-shipping' );     // Shipping methods on which adjustment has to be applied
    
            $adjustment = 0;
    
            foreach( $package['contents'] as  $line_item ) {
                $line_item_shipping_class = $line_item['data']->get_shipping_class();
                if( ! empty($line_item_shipping_class) ) {
                    foreach( $handling_fee_based_on_shipping_class as $adjustment_data ) {
                        if( in_array( $line_item_shipping_class, $adjustment_data['shipping_classes']) ) {
                            $adjustment += $adjustment_data['adjustment'] * $line_item['quantity'];
                        }
                    }
                }
            }
    
            if( $adjustment > 0 ) {
                foreach( $shipping_rates as $shipping_rate ) {
                    $shipping_method_id = $shipping_rate->get_method_id();
                    if( in_array($shipping_method_id, $shipping_method_ids) ) {
                        $shipping_rate->set_cost( (float) $shipping_rate->get_cost() + $adjustment );
                    }
                }
            }
    
            return $shipping_rates;
        }
    }
    

    It should work handling car item quantity additional cost…

    Don't forget to refresh shipping methods going to shipping settings, then disable/save and re-enable/save any shipping method in the related shipping zone.

    Other answer threads related to woocommerce_package_rates hook.