I am running a BOGO on one item. The problem with this is when you increase the quantity of bought item, the given free item quantity doesnt increase with it.
How can we make them act as one like so that both the items have same quantity?
I am trying to make changes to this code so that it does the job.
add_action( 'template_redirect', 'bbloomer_add_gift_if_id_in_cart' );
function bbloomer_add_gift_if_id_in_cart() {
if ( is_admin() ) return;
if ( WC()->cart->is_empty() ) return;
$product_bought_id = 874;
$product_gifted_id = 870;
// see if product id in cart
$product_bought_cart_id = WC()->cart->generate_cart_id( $product_bought_id );
$product_bought_in_cart = WC()->cart->find_product_in_cart( $product_bought_cart_id );
// see if gift id in cart
$product_gifted_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
$product_gifted_in_cart = WC()->cart->find_product_in_cart( $product_gifted_cart_id );
// if not in cart remove gift, else add gift
if ( ! $product_bought_in_cart ) {
if ( $product_gifted_in_cart ) WC()->cart->remove_cart_item( $product_gifted_in_cart );
} else {
if ( ! $product_gifted_in_cart ) WC()->cart->add_to_cart( $product_gifted_id );
}
}
The code you are using is will not work if the customer removes the gifted product ID. In this case, the gifted product will be deleted after the page has been reloaded.
So woocommerce_before_calculate_totals
is recommended over template_redirect
My answer contains:
Than you get:
function action_woocommerce_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// SETTINGS
$product_bought_id = 30;
$product_gifted_id = 815;
// END SETTINGS
// Flags
$product_bought_in_cart = false;
$gifted_key = false;
// Loop trough
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Product ID in cart
$product_id_in_cart = $cart_item['product_id'];
// Check if product bought is in cart
if ( $product_id_in_cart == $product_bought_id ) {
// True
$product_bought_in_cart = true;
// Product quantity in cart
$product_bought_in_cart_quantity = $cart_item['quantity'];
}
// Check if product gifted is in cart
if ( $product_id_in_cart == $product_gifted_id ) {
// Set gifted key (true)
$gifted_key = $cart_item_key;
}
}
// If product bought is false & gifted key is true
if ( ! $product_bought_in_cart && $gifted_key ) {
$cart->remove_cart_item( $gifted_key );
// If product bought in true & gifted key is false
} elseif ( $product_bought_in_cart && ! $gifted_key ) {
$cart->add_to_cart( $product_gifted_id, $product_bought_in_cart_quantity );
// If product bought in true & gifted key is true
} elseif ( $product_bought_in_cart && $gifted_key ) {
$cart->set_quantity( $gifted_key, $product_bought_in_cart_quantity );
}
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );
jQuery
part, ensures that the quantity fields are adjusted simultaneously
function action_wp_footer() {
// SETTINGS
$product_bought_id = 30;
$product_gifted_id = 815;
// END SETTINGS
// See if product id in cart
$product_bought_cart_id = WC()->cart->generate_cart_id( $product_bought_id );
$product_bought_in_cart = WC()->cart->find_product_in_cart( $product_bought_cart_id );
// See if gift id in cart
$product_gifted_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
$product_gifted_in_cart = WC()->cart->find_product_in_cart( $product_gifted_cart_id );
// Both true
if ( $product_bought_in_cart && $product_gifted_in_cart ) {
?>
<script>
jQuery(function($) {
// Selectors
var product_bought_in_cart_selector = $( "input[name*='<?php echo $product_bought_in_cart; ?>']" );
var product_gifted_in_cart_selector = $( "input[name*='<?php echo $product_gifted_in_cart; ?>']" );
// When 1 of the 2 quantity fields are updated, these values change similarly
$( product_bought_in_cart_selector ).change(function() {
var product_bought_in_cart_selector_quantity = $( this ).val();
$( product_gifted_in_cart_selector ).val( product_bought_in_cart_selector_quantity );
});
$( product_gifted_in_cart_selector ).change(function() {
var product_gifted_in_cart_selector_quantity = $( this ).val();
$( product_bought_in_cart_selector ).val( product_gifted_in_cart_selector_quantity );
});
});
</script>
<?php
}
}
add_action( 'wp_footer', 'action_wp_footer');
Optional 1: A warning that the gift product cannot be purchased separately
function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
// SETTINGS
$product_gifted_id = 815;
// True
if ( $product_gifted_id == $product_id ) {
// Add notice
wc_add_notice( __( 'This is a gift item and cannot be purchased separately', 'woocommerce' ), 'error' );
// NOT passed
$passed = false;
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );
Optional 2: Ensures that the gift product is not individually removable in the shopping cart
function filter_woocommerce_cart_item_remove_link( $link, $cart_item_key ) {
// SETTINGS
$product_gifted_id = 815;
// Cart id
$product_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
// Find product in cart
$in_cart_key = WC()->cart->find_product_in_cart( $product_cart_id );
// True
if ( $in_cart_key == $cart_item_key ) {
$link = '';
}
return $link;
}
add_filter( 'woocommerce_cart_item_remove_link', 'filter_woocommerce_cart_item_remove_link', 10, 2 );
Optional 3: Make sure that the order cannot be fulfilled if the quantity of both products is not equal
function action_woocommerce_check_cart_items() {
// SETTINGS
$product_bought_id = 30;
$product_gifted_id = 815;
// END SETTINGS
// Loop though cart items searching for the defined product
foreach( WC()->cart->get_cart() as $cart_item ) {
// Product id
$product_id = $cart_item['product_id'];
if ( $product_bought_id == $product_id ) {
$product_bought_quantity = $cart_item['quantity'];
$product_bought_name = $cart_item['data']->get_name();
}
if ( $product_gifted_id = $product_id ) {
$product_gifted_quantity = $cart_item['quantity'];
$product_gifted_name = $cart_item['data']->get_name();
}
}
// Isset & NOT equal
if( isset ( $product_bought_quantity ) && isset ( $product_gifted_quantity ) && $product_bought_quantity != $product_gifted_quantity ) {
wc_add_notice( sprintf(
__( 'The quantity of %s and %s must be equal before you can continue', 'woocommerce' ),
$product_bought_name,
$product_gifted_name,
), 'error' );
// Removing the proceed button, until the condition is met
// optional
remove_action( 'woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20);
}
}
add_action( 'woocommerce_check_cart_items', 'action_woocommerce_check_cart_items', 10, 0 );