1

For WooCommerce, I try to use the following 2 code snippets: The first one adds a "winter" product at 0 cost if the cart reaches €40. This works.

Then I have the second code snippet that if I add a "summer" coupon it should remove the "winter" product added by default earlier, but it doesn't, what am I doing wrong?

Based on Add free gifted product for a minimal cart amount in WooCommerce answer, here is my First working snippet:

// Add free gifted product for specific cart subtotal
add_action( 'woocommerce_before_calculate_totals', 'check_free_gifted_product' );
function check_free_gifted_product( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Settings
    $free_product_id   = 90;
    $targeted_subtotal = 20;

    $cart_subtotal     = 0; // Initializing

    // Loop through cart items (first loop)
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
        // When free product is is cart
        if ( $free_product_id == $cart_item['product_id'] ) {
            $free_key = $cart_item_key;
            $free_qty = $cart_item['quantity'];
            $cart_item['data']->set_price(0); // Optionally set the price to zero
        } else {
            $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
        }
    }

    // If subtotal match and free product is not already in cart, add it
    if ( ! isset($free_key) && $cart_subtotal >= $targeted_subtotal ) {
        $cart->add_to_cart( $free_product_id );
    }

}

// Display free gifted product price to zero on minicart
add_filter( 'woocommerce_cart_item_price', 'change_minicart_free_gifted_item_price', 10, 3 );
function change_minicart_free_gifted_item_price( $price_html, $cart_item, $cart_item_key ) {
    $free_product_id   = 90;
    
    if( $cart_item['product_id'] == $free_product_id ) {
        return wc_price( 0 );
    }
    return $price_html;
}

second snippet not working

function remove_free_product($cart) {
    /**
     * This function removes a free product "winter" from the cart if a coupon "summer" is applied.
     * 
     * Parameters:
     * $cart (array): An array containing the cart items and their details
     * 
     * Returns:
     * array: The updated cart array
     */
    try {
        // Check if the cart is empty
        if (empty($cart)) {
            throw new Exception("Cart is empty");
        }
        
        // Check if the coupon "summer" is applied
        $coupon_applied = false;
        foreach ($cart as $item) {
            if ($item['coupon'] == 'summer') {
                $coupon_applied = true;
                break;
            }
        }
        
        // Remove the free product "winter" if the coupon "summer" is applied
        if ($coupon_applied) {
            foreach ($cart as $key => $item) {
                if ($item['product'] == 'winter' && $item['price'] == 20) {
                    unset($cart[$key]);
                    break;
                }
            }
        }
        
        // Return the updated cart
        return $cart;
    } catch (Exception $e) {
        // Log the error
        error_log("Error: " . $e->getMessage());
        return array();
    }
}

or rather, nothing happens, it updates the cart if I enter the coupon "summer" but it doesn't remove "winter"

Tnx e.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399

1 Answers1

0

The following revisited code should do everything as expected, adding a free product when cart subtotal reaches a specific minimal amount and if "summer" coupon is not applied to cart.

So when the free product is in the cart, if customer change cart removing some items and cart subtotal is below the specific amount, or if "summer" coupon is applied to cart, the free product will be removed.

Here is the code:

// Free gifted product for specific cart subtotal and no "summer" coupon
add_action( 'woocommerce_before_calculate_totals', 'check_free_gifted_product' );
function check_free_gifted_product( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Settings
    $free_product_id   = 90;
    $targeted_subtotal = 20;
    $coupon_code       = "summer"; // coupon code
    $cart_subtotal     = 0; // Initializing

    // Loop through cart items (first loop)
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
        // When free product is is cart
        if ( $free_product_id == $cart_item['product_id'] ) {
            $free_key = $cart_item_key;
            $free_qty = $cart_item['quantity'];
            $cart_item['data']->set_price(0); // Optionally set the price to zero
        } else {
            $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
        }
    }

    // If subtotal match and free product is not already in cart, add it
    if ( ! isset($free_key) && $cart_subtotal >= $targeted_subtotal && ! $cart->has_discount( $coupon_code ) ) {
        $cart->add_to_cart( $free_product_id );
    }
    // If subtotal doesn't match or coupon "summer" is applied and free product is already in cart, remove it
    elseif ( ( $cart_subtotal < $targeted_subtotal || $cart->has_discount( $coupon_code ) ) && isset($free_key) ) {
        $cart->remove_cart_item( $free_key );
    }
}

// Display free gifted product price to zero on minicart
add_filter( 'woocommerce_cart_item_price', 'change_minicart_free_gifted_item_price', 10, 3 );
function change_minicart_free_gifted_item_price( $price_html, $cart_item, $cart_item_key ) {
    $free_product_id   = 90;
    
    if( $cart_item['product_id'] == $free_product_id ) {
        return wc_price( 0 );
    }
    return $price_html;
}

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

Related: Add free gifted product for a minimal cart amount in WooCommerce

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Hi and thanks for the reply and the modified code, but I have a problem, if I use another coupon which is not "summer" but "abc" which has a 100% discount it also removes the free "winter" product, I have need only some coupons remove "winter" and not all. example: User A buys product "fish" (id 123) and exceeds 40€, gets "winter" cost 0 as a gift, adds coupon "ABC" and gets everything free User B buys product "fish" (id 123) and exceeds 40€, gets "winter" for free cost 0, adds coupon "summer" and has only the first product ("fish") free but "winter" is removed I need both possibilities e. – eros casula Jun 07 '23 at 20:23
  • Sorry, but my code is tested and works for what you asked in your initial question. If you have another question, please ask a new question providing in a clear way **your code attempt** and all necessary details and explanations related to your code issue... – LoicTheAztec Jun 07 '23 at 20:26