• Resolved gdelta

    (@gdelta)


    I’m trying to apply a Free Shipping shipping method in my store, but without sale products. So the total amount (price) of the cart should ignore all products that are on sale. The minimum Free Shipping amount should only be compared to the total amount of regular (not sale) products in the cart.

    How can I get this to work?

    I’ve tried to use the woocommerce_package_rates hook to unset (unset($rates[$rate_id]);) the free_shipping rate if min_amount has a higher value than the sum of all regular products in cart. This does not work.

    However, when I make the same check directly on the cart page the condition does seem to work.

    Below my code (what I’ve tried so far) inside functions.php

    add_filter( 'woocommerce_package_rates', 'my_function', 10, 2 );
    function my_function( $rates, $package ) {

    $sale_items_in_cart = false;
    $normal_items_in_cart = false;

    $sale_items_in_cart_price_total = 0;
    $normal_items_in_cart_price_total = 0;

    foreach ( WC()->cart->get_cart() as $key => $values ) {

    if ( $values[ 'data' ]->get_sale_price() && !$sale_items_in_cart ) {
    $sale_items_in_cart = true;
    }

    if ( !$values[ 'data' ]->get_sale_price() && !$normal_items_in_cart ) {
    $normal_items_in_cart = true;
    }

    if ( $values[ 'data' ]->get_sale_price() ) {
    $sale_items_in_cart_price_total += $values[ 'data' ]->get_sale_price() * $values['quantity'];
    }
    else {
    $normal_items_in_cart_price_total += $values[ 'data' ]->get_price() * $values['quantity'];
    }

    }

    if ( ( $sale_items_in_cart && $normal_items_in_cart ) || !$sale_items_in_cart ) {

    $free = false;

    foreach ( $rates as $rate_id => $rate ) {

    if ( 'free_shipping' === $rate->method_id ) {

    $rate_data = get_option('woocommerce_' . $rate->method_id . '_' . $rate_id . '_settings');

    if ( isset($rate_data['min_amount']) && floatval($normal_items_in_cart_price_total) <= floatval($rate_data['min_amount']) ) {

    $free = false;
    unset($rates[$rate_id]);

    }
    else {

    $free = true;

    }

    break;

    }

    }

    if ( $free ) {

    foreach ( $rates as $rate_key => $rate ) {

    if ( 'flat_rate' === $rate->method_id ) {
    unset($rates[$rate_key]);
    }

    }

    }

    }

    return $rates;

    }

Viewing 2 replies - 1 through 2 (of 2 total)
  • Plugin Support Reynier C. (woo-hc)

    (@reynierc)

    Hi @gdelta ,

    I see what you’re trying to do with your Free Shipping settings and that your current approach isn’t producing the results you want.

    It can be tricky getting the conditions right. What you might need to do is adjust your code to specifically exclude the sale item prices from the total when checking against your free shipping minimum.

    Remember to check if your free shipping method is enabled and properly configured to respond to these custom conditions in your code.

    If you need further help with the code, please note that custom code falls outside our scope of support, in this case we recommend asking your development questions in the ?WooCommerce Community Slack?. Many of our developers are active there and can help. You can also get help from the following:

    If editing the custom code isn’t working out, you may want to consider using a plugin designed for advanced shipping rules. Plugins like ‘WooCommerce Advanced Free Shipping‘ can often provide a more user-friendly way to set up complex shipping conditions without getting into the code. Just in case you need help with this third-party plugin, it would be best to reach out to the developers as they are best equipped about their plugin.

    Hope this helps!

    Plugin Support Feten L. a11n

    (@fetenlakhal)

    Hi! Since we haven’t heard back, I’ll go ahead and mark this as closed for now. We’ll be here whenever you’re ready to reconnect.

Viewing 2 replies - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.