Search code examples
wordpresswoocommerceadvanced-custom-fieldshook-woocommerceshipping-method

Change shipping cost depending on ACF field and exclude certain shipping methods


I'm trying to add an extra shipping cost for all the additional shipping fees that aren't calculated from the third party shipping company:

//add additional extra cost to shipping except for local pickup
    
        add_filter( 'woocommerce_package_rates', 'shipping_extra_cost' );
        function shipping_extra_cost( $rates ) {
        
            
            foreach($rates as $key => $rate ) {
                $rates[$key]->cost = $rates[$key]->cost + get_field('extra_cost', "51");
            }
    
        return $rates;
    }

But then the additional fee is also added on local shipping which is wrong.

I can't work with WC shipping classes because that messes with the third party shipping calculation program.

Is there a way I can check if "local pickup" exists and then exclude the extra fee from it?


Solution

  • You can exclude 1 or more shipping methods by using $rate->method_id

    Note: because get_field() only applies when using the ACF plugin I replaced it with a fixed number, adjust to your needs

    So you get:

    function filter_woocommerce_package_rates( $rates, $package ) {
        //$field = get_field( 'extra_cost', '51' );
    
        $field = 50;
    
        // Multiple can be added, separated by a comma
        $exclude = array( 'local_pickup' );
    
        // Loop through
        foreach ( $rates as $rate_key => $rate ) {
            // Targeting
            if ( ! in_array( $rate->method_id, $exclude ) ) {
                // Set the new cost
                $rates[$rate_key]->cost += $field;
            }
        }
    
        return $rates;
    }
    add_filter( 'woocommerce_package_rates','filter_woocommerce_package_rates', 10, 2 );
    

    For debugging purposes you can temporarily use:

    function filter_woocommerce_cart_shipping_method_full_label( $label, $method ) {
        // Getters
        $id = $method->id;
        $method_id = $method->method_id;
    
        // Output
        $label .= '<span style="color:red; font-size:20px; display:block;">Id = ' . $id . '</span>';
        $label .= '<span style="color:red; font-size:20px; display:block;">Method id = ' . $method_id . '</span>';
    
        return $label; 
    }
    add_filter( 'woocommerce_cart_shipping_method_full_label', 'filter_woocommerce_cart_shipping_method_full_label', 10, 2 );
    

    Result:

    enter image description here