0

Thanks to LoicTheAztec I have almost perfect 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;
}

But unfortunately, I have a variant that I didn't specify in Remove free product if specific coupon is applied to cart in WooCommerce previous post and this is fundamental.

If I use another coupon in the above code which is not "summer" but "abc" which has a 100% discount, it also removes the "winter" product for free, some coupons are enough for me to remove "winter" and not everything. Example:

User purchases the product "fish" (id 123) and exceeds €40, receives "winter" as a gift for 0, adds coupon "abc" and gets everything for free ("fish" + "winter")

User B buys the product "fish" (id 123) and exceeds €40, gets "winter" free cost 0, but when he adds the coupon "summer" he only gets the first product ("fish") free but "winter" is taken away.
I need both options.

Here are screenshots for clarification:

tpirat.com/1.png

tpirat.com/2.png

tpirat.com/3.png

Hello, maybe I fixed it, it's not very elegant but it works:

add_action( 'woocommerce_before_calculate_totals', 'check_free_gifted_product' );
function check_free_gifted_product( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    $free_product_id   = 32717;
    $targeted_subtotal = 20;
    $coupon_codes      = array( "abc", "summer", "123" ); // coupon codes
    $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 ( ! in_array( 'abc', $cart->get_applied_coupons() ) && 
        ! in_array( 'summer', $cart->get_applied_coupons() ) && 
        ! in_array( '123', $cart->get_applied_coupons() ) && 
        ! isset( $free_key ) && $cart_subtotal >= $targeted_subtotal ) {
        $cart->add_to_cart( $free_product_id );
    }
    // If coupon "abc" or "summer" is applied and free product is already in cart, remove it
    elseif ( ( in_array( 'abc', $cart->get_applied_coupons() ) || in_array( 'abc', $cart->get_applied_coupons() ) ||in_array( '123', $cart->get_applied_coupons() ) ) && 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   = 32717;

    if( $cart_item['product_id'] == $free_product_id ) {
        return wc_price( 0 );
    }
    return $price_html;
}

0 Answers0