Allow only 1 quantity of particular product in cart WooCommerce - php

I have one variable product X that product has two variations, Variations A and Variations B.
If a customer added variation A in cart then I want to block the customer to add variations B in cart. At a time customer only order one of variations of that product.
I have added below code but it's not working well because if I added one variations of product X in cart then I tried to add another product Y in the cart it's not adding to cart.
My code current code is the following.
function wph_add_the_cart_validation_for_zoomarine_e_ticket( $passed ) {
// The product id of variable product X
$product_id = 44050;
$in_cart = false;
foreach( WC()->cart->get_cart() as $cart_item ) {
$product_in_cart = $cart_item['product_id'];
if ( $product_in_cart === $product_id ) $in_cart = true;
}
if ( $in_cart ) { ?>
<script type="text/javascript">
alert("The product is already in cart. You can only add one E ticket per order");
</script>
<?php
$passed = false;
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'wph_add_the_cart_validation_for_zoomarine_e_ticket', 10, 5 );

The following code solved my issue.I got the answer from here https://wordpress.stackexchange.com/questions/349916/allow-only-1-quantity-of-particular-product-in-cart-woocommerce/349929#349929
add_filter( 'woocommerce_add_to_cart_validation', 'allowed_products_variation_in_the_cart', 10, 5 );
function allowed_products_variation_in_the_cart( $passed, $product_id, $quantity, $variation_id, $variations) {
$product_a = 14576;
$product_b = 14091;
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$cart_product_id = $cart_item['product_id'];
if ($cart_item['variation_id']) {
$cart_product_id = $cart_item['variation_id'];
}
if ( ($cart_product_id == $product_a && $variation_id == $product_b) || ($cart_product_id == $product_b && $variation_id == $product_a) ) {
wc_add_notice(__('You can\'t add this product.', 'domain'), 'error');
$passed = false; // don't add the new product to the cart
// We stop the loop
break;
}
}
return $passed;
}

Related

Add or remove automatically a free product in Woocommerce cart but not with subscription product on the cart

Hello this is similar question to the link below but just want to ask if it's possible to set a condition where it won't load the free product if the product that's been purchase is a subscription type? Thank you.
Add or remove automatically a free product in Woocommerce cart
/**
* Add another product depending on the cart total
*/
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
global $woocommerce;
$product_id = 85942; //replace with your product id
$found = false;
$cart_total = 15; //replace with your cart total needed to add above item
if( $woocommerce->cart->total >= $cart_total ) {
//check if product already in cart
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
$isVirtualOnly = false;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
$_product = $values[‘data’];
if ($_product != null)
if ($_product->get_type() != $_virtual)
$isVirtualOnly = false;
}
if ($isVirtualOnly != true) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->get_id() == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
$woocommerce->cart->add_to_cart( $product_id );
}
} else {
// if no products in cart, add it
$woocommerce->cart->add_to_cart( $product_id );
}
}
}
}
/**
* END Add another product depending on the cart total
*/
add_action( 'template_redirect', 'add_product_to_cart_conditionally' );
function add_product_to_cart_conditionally() {
if ( is_admin() ) return; // Exit
// Below define the product Id to be added:
$product_A = 37; // <== For new customers that have not purchased a product before (and guests)
$product_B = 53; // <== For confirmed customers that have purchased a product before
$product_id = has_bought() ? $product_B : $product_A;
// If cart is empty
if( WC()->cart->is_empty() ) {
WC()->cart->add_to_cart( $product_id ); // Add the product
}
// If cart is not empty
else {
// Loop through cart items (check cart items)
foreach ( WC()->cart->get_cart() as $item ) {
// Check if the product is already in cart
if ( $item['product_id'] == $product_id ) {
return; // Exit if the product is in cart
}
}
// The product is not in cart: We add it
WC()->cart->add_to_cart( $product_id );
}
}

Add Variable product into cart automatically when cart total is more than 25

I want to add automatically one variations product into cart when cart total is become more than 25. The automatically adding variation product price need to set as 0 and also customers cant change the qty or need to disable the Qty filed for free product. I added below code and its working fine only the issue when page reloading or cart updating the the Qty of free product is increasing every time.I only want to sell 1 qty of free product. How to do that ? Code is following below.
function aapc_add_product_to_cart() {
global $woocommerce;
$cart_total = 25;
if ( $woocommerce->cart->total >= $cart_total ) {
if ( ! is_admin()) {
$free_product_id = 2696;
$variation_id = 2697;
$arr = array();
$arr['Color'] = 'Blue';// Product Id of the free product which will get added to cart
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->get_id() == $free_product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $free_product_id,1,$variation_id,$arr );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $free_product_id,1,$variation_id,$arr );
}
}
}
}
add_action( 'template_redirect', 'aapc_add_product_to_cart' );
function add_custom_price( $cart_object ) {
$cart_total = 25; // If cart total is more than this value.
$free_product_id = 2697; // Set price to 0 of this free product.
$carttotal = 0;
foreach ( $cart_object->cart_contents as $key => $value ) {
$_product = $value['data'];
if ( $_product->get_id() == $free_product_id ){
continue;
}
$carttotal += $value['line_total'];
}
if ( $carttotal >= $cart_total ) {
$custom_price = 0; // This will be your custome price
foreach ( $cart_object->cart_contents as $key => $value ) {
$_product = $value['data'];
if ( $_product->get_id() == $free_product_id ){
$value['data']->set_price( $custom_price );
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
add_filter( 'woocommerce_quantity_input_args', 'hide_quantity_input_field', 20, 2 );
function hide_quantity_input_field( $args, $product ) {
// Here set your product IDs in the array
$product_ids = array(2697);
// Handling product variation
$the_id = $product->is_type('variation') ? $product->get_variation_id() : $product->get_id();
//var_dump($the_id);
// Only on cart page for a specific product category
if( is_cart() && in_array( $the_id, $product_ids ) ){
$input_value = $args['input_value'];
$args['min_value'] = $args['max_value'] = $input_value;
}
return $args;
}
Try adding below code in the functions.php and replace with required product id
add_filter( 'woocommerce_add_to_cart_validation', 'allowed_products_variation_in_the_cart', 10, 5 );
function allowed_products_variation_in_the_cart( $passed, $product_id, $quantity, $variation_id, $variations) {
$product_b = 14091;
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$cart_product_id = $cart_item['product_id'];
if ($cart_item['variation_id']) {
$cart_product_id = $cart_item['variation_id'];
}
if ( ( $variation_id == $product_b) ) {
wc_add_notice(__('You can\'t add this product.', 'domain'), 'error');
$passed = false; // don't add the new product to the cart
// We stop the loop
break;
}
}
return $passed;
}

Automatically recalculate quantity when clicking on update cart in Woocommerce

So by using the docs on the WooCommerce site I've been able to add a new product to the basket automatically which works great.
I calculate the number of products by taking the current quantity in the cart and multiplying it by a percentage modifier, this also works.
My problem comes when I update the cart with a new quantity as the bonus product quantity doesn't get updated.
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 265;
$found = false;
// Get the current cart quantity
foreach ( WC()->cart->get_cart() as $cart_item ) {
$quantity = $cart_item['quantity'];
$percentage = .25;
$bonus = $quantity * $percentage;
}
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id, $bonus );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id, $bonus );
}
}
}
Does anyone have an idea on how to get this to automatically recalculate when update cart is clicked?
Preliminary remarks:
Your code doesn't work when cart is empty as $bonus variable is not defined and you get an error…
Also as you are setting a variable float number for quantity: So if the quantity is not an integer, customer can't change and update the cart items quantities.
This is kind of complex, your bonus quantity need to be updated in another hooked function when:
A product is added to cart
Customer update quantities in cart page
Customer remove items from cart
Also, there is small errors like $_product->id that should instead $_product->get_id() in WC 3+
So your revisited code with additional hooked functions will be:
add_action( 'template_redirect', 'auto_add_product_to_cart', 50 );
function auto_add_product_to_cart() {
if ( ! is_admin() ) {
$cart = WC()->cart; // <== Cart object
$product_id = 37; // <== Specific product to be auto added
$bonus_rate = .25; // <== Bonus rate
$found = false;
// Check if product already in cart
if ( ! $cart->is_empty() ) {
$contents_count = $cart->get_cart_contents_count(); // The cart items count
$bonus_qty = $contents_count * $bonus_rate; // Bonus quantity calculation
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
if ( $cart_item['data']->get_id() == $product_id ){
$found = true;
break; // Stop the loop
}
}
// Product is not found in the loop, we add it
if( ! $found )
$cart->add_to_cart( $product_id, $bonus_qty );
} else {
// There is no items in cart, we add it
$cart->add_to_cart( $product_id, $bonus_rate );
}
}
}
// Calculate, set and update bonus quantity
add_action( 'woocommerce_before_calculate_totals', 'conditional_bonus_quantity_calculation', 20, 1 );
function conditional_bonus_quantity_calculation( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$bonus_rate = .25; // <== Bonus rate
$product_id = 37; // <== Specific product to be auto added
$contents_count = $cart->get_cart_contents_count(); // Total cart items count
// Loop through cart items to check our specific product
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// If specific product is in cart
if ( $cart_item['data']->get_id() == $product_id ){
$calc_qty = $cart_item['quantity'] < 1 ? 1 : $cart_item['quantity'];
// Bonus quantity calculation
if( $contents_count > 1 )
$bonus_qty = round( $contents_count - $calc_qty ) * $bonus_rate;
else
$bonus_qty = $bonus_rate;
// Update item quantity
$cart->set_quantity( $cart_item_key, $bonus_qty, false );
}
}
}
// Allowing float numbers quantity (step by .25) for a specific product
add_filter( 'woocommerce_quantity_input_args', 'custom_quantity_input_args', 20, 2 );
function custom_quantity_input_args( $args, $product ) {
// Only for your specific product ID on cart page
if( $product->get_id() != 37 && is_cart() ) return $args;
//$args['input_value'] = 0.25; // Default starting value (Optional)
$args['min_value'] = 0.25;
$args['step'] = 0.25;
$args['pattern'] = '[0-9.]*';
$args['inputmode'] = 'numeric';
return $args;
}
// Allowing float numbers in Stock management
remove_filter('woocommerce_stock_amount', 'intval');
add_filter('woocommerce_stock_amount', 'floatval');
Code goes in function.php file of the active child theme (or active theme).
Tested and works.

Woocommerce sold individually feature based on product categories

I have a woocommerce site I use the booster plugin to enable sold individually for each product but now I want to sold individually for each category and if someone add a product to cart on a category then can not add another product of that category to cart
In the code below there is 2 functions:
The 1st one is a conditional function checking categories in cart items
The 2nd one will avoid add to cart when a product category already exist in cart items and will display a custom message.
The code:
// Conditional function: Checking product categories in cart items
function check_cats_in_cart( $product_id ) {
$taxonomy = 'product_cat';
$has_term = true;
foreach( WC()->cart->get_cart() as $item ){
foreach( wp_get_post_terms( $item['product_id'], $taxonomy ) as $term ){
// Allowing add to cart the same product
if( has_term( $term->slug, $taxonomy, $product_id ) ){
$has_term = false;
break; // stops the 2nd loop
}
}
// Allowing the same product to be added (not activated. you can uncomment lines below)
# if ( $item['product_id'] == $product_id )
# $has_term = true;
if( $has_term )
break; // stops the 1st loop
}
return $has_term;
}
// Avoid add to cart when a product category already exist in cart items, displaying a custom error message
add_filter( 'woocommerce_add_to_cart_validation', 'sold_individually_by_cats_valid', 10, 3 );
function sold_individually_by_cats_valid( $passed, $product_id, $quantity) {
$passed = check_cats_in_cart( $product_id );
if( ! $passed ){
// Displaying a custom message
$message = __("This product category is already in cart. Try another product", "woocommerce");
wc_add_notice( $message, 'error' );
}
return $passed;
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.
If you want to allow adding to cart again the same product (that increases only the quantity of an existing product), you will uncomment this code in the function:
if ( $item['product_id'] == $product_id )
$has_term = true;
You can try it this one
function is_product_the_same_cat($valid, $product_id, $quantity) {
global $woocommerce;
if($woocommerce->cart->cart_contents_count == 0){
return true;
}
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
$terms = get_the_terms( $_product->id, 'product_cat' );
$target_terms = get_the_terms( $product_id, 'product_cat' );
foreach ($terms as $term) {
$cat_ids[] = $term->term_id;
}
foreach ($target_terms as $term) {
$target_cat_ids[] = $term->term_id;
}
}
$same_cat = array_intersect($cat_ids, $target_cat_ids);
if(count($same_cat) > 0) return $valid;
else {
wc_add_notice( 'This product is in another category!', 'error' );
return false;
}
}
add_filter( 'woocommerce_add_to_cart_validation', 'is_product_the_same_cat',10,3);
I found it from here

certain product are single product in cart woocommerce

Certain products when have tag value "buynow" or categories by featue products added to cart I want to remove all other product in cart and dont allow to add more product in cart. When one user added one product of this type and tries to add another product in cart, It will show error notice.
I have tried this code for product id 1024
add_filter( 'woocommerce_add_cart_item_data', 'wdm_empty_cart', 10, 3);
function wdm_empty_cart( $cart_item_data, $product_id, $variation_id )
{
global $woocommerce;
if($product_id == '1024'){
$woocommerce->cart->empty_cart();
wc_add_notice( 'Error!', 'error' );
}
elseif ( WC()->cart->get_cart_contents_count() >=1 ){
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = $values['data']->post;
$cartproductid[] = $_product->ID;
}
foreach($cartproductid as $id){
if($id == 1024){
wc_add_notice( 'Error!', 'error' );
$woocommerce->cart->empty_cart();
$woocommerce->cart->add_to_cart('1024');
}
}
}
return $cart_item_data;
}
My code works as follows:
When user add 1024 product id to the cart it empty the cart and add only the 1024 product. when user add product after adding 1024 not the same product it adds one more to the cart the stops adding further product.
My requirement is when 1024 product added to the cart no other product can not add to the cart. When user try to add it shows the notice "Error!"
Any solution is appreciated. Thanks in advance.
Anyone's help appreciated.
Instead of woocommerce_add_cart_item_data you can use woocommerce_add_to_cart_validation. this works.
add_filter( 'woocommerce_add_to_cart_validation', 'woocommerce_add_to_cart_validation_CB', 30, 3);
function woocommerce_add_to_cart_validation_CB( $bool, $product_id, $quantity )
{
global $woocommerce;
if($product_id == '1024'){
$woocommerce->cart->empty_cart();
}
elseif ( WC()->cart->get_cart_contents_count() >= 1 ){
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
if( '1024' == $values['product_id'] ){
wc_add_notice( 'Error!', 'error' );
return false;
}
}
}
return $bool;
}
If you want do this for featured product then use following code.
add_filter( 'woocommerce_add_to_cart_validation', 'woocommerce_add_to_cart_validation_CB', 30, 3);
function woocommerce_add_to_cart_validation_CB( $bool, $product_id, $quantity )
{
global $woocommerce;
if( isFeaturedProduct($product_id)){
$woocommerce->cart->empty_cart();
}
elseif ( WC()->cart->get_cart_contents_count() >= 1 ){
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
if(isFeaturedProduct($values['product_id']) ){
wc_add_notice( 'Error!', 'error' );
return false;
}
}
}
return $bool;
}
function isFeaturedProduct( $product_id ){
$wc_product_obj = new WC_Product($product_id);
return $wc_product_obj->is_featured();
}

Categories