I'm using the following code to add a free product to the basket when over a certain cart total.
When I drop below the cart total it hits the if statement but won't remove the product.
I think this may be because the quantity is set to 1 on the basket form and my code isn't overriding that quantity to set it to 0 (and remove it).
Is there another way to remove it or override it?
/*
* Automatically adding the product to the cart when cart total amount reach to £20.
*/
function aapc_add_product_to_cart() {
global $woocommerce;
$cart_total = 20;
$free_product_id = 85028; // Product Id of the free product which will get added to cart
if ( $woocommerce->cart->total >= $cart_total ) {
echo "Over the limit";
$quantity = 1;
WC()->cart->add_to_cart( $free_product_id, $quantity );
} elseif($woocommerce->cart->total < $cart_total) {
echo "Under the limit";
$quantity = 0;
WC()->cart->remove_cart_item( $free_product_id, $quantity );
}
}
add_action( 'template_redirect', 'aapc_add_product_to_cart' );
I've tried using this question but cannot get it to work, it won't even add the item to my basket.
I'm using Woocommerce version 3.6.5 if that helps.
I'm not sure on how Woocommerce works but I assume the remove_cart_item 'quantity' parameter takes the amount of the item to remove from the basket. So set the value of $quantity to 1 and it should remove one of the free product from the basket. If there happens to be more than one free item in the basket then you'll need to set your $quantity value accordingly.
Furthermore, you are adding a free item every time a product is added when the basket value is higher than $cart_total. Maybe add a check to see if it already exists in the basket before adding it?
Hope I understood your question correctly
/*
* Automatically adding the product to the cart when cart total amount reach to £20.
*/
function aapc_add_product_to_cart() {
global $woocommerce;
$cart_total = 20;
$free_product_id = 85028; // Product Id of the free product which will get added to cart
if ( WC()->cart->total >= $cart_total ) {
$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 );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $free_product_id );
}
} elseif(WC()->cart->total < $cart_total) {
$quantity = 0;
$prod_unique_id = WC()->cart->generate_cart_id( $free_product_id );
// Remove it from the cart by un-setting it
unset( WC()->cart->cart_contents[$prod_unique_id] );
WC()->cart->remove_cart_item( $free_product_id );
}
}
add_action( 'woocommerce_after_calculate_totals', 'aapc_add_product_to_cart' );
Related
I'm trying to figure out how to add a specific item to cart, if this variation ID is added to cart. For example I have like 4 variations of a configurable product.
11264
11265
11266
11267
If product variation 11264 and 11265 is added to cart, then product with product ID 111 should also be added to cart. If 11266 and 11267 is added to cart, then product with product ID 222 should also be added to cart.
I found this code online that can add an item to cart based on the product category:
function aaptc_add_product_to_cart( $item_key, $product_id ) {
$product_category_id = 123; // cricket bat category id
$product_cats_ids = wc_get_product_term_ids( $product_id, 'product_cat' );
if ( ! is_admin() && in_array( $product_category_id, $product_cats_ids ) ) {
$free_product_id = 1522; // 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 );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $free_product_id );
}
}
}
add_action( 'woocommerce_add_to_cart', 'aaptc_add_product_to_cart', 10, 2 );
That code works as intended. But now I want to make it conditional. So I modified this line:
if ( ! $found )
WC()->cart->add_to_cart( $free_product_id );
And changed it to:
if ($found && WC()->cart->(11264,11265))
WC()->cart->add_to_cart(111);
So that if variation ID 11264 or 11265 exists in cart, then add product ID 111. I think my syntax is wrong, but I'm not sure what's the next step. Tried googling it for hours but I cannot find any decent examples.
Slight Modification in foreach loop to get & compare variations might resolve the issue
foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
$variation_ids = array(11264,11265);
//check if variation exist in cart & if found add product in cart with ID 111
if( in_array( $values['variation_id'], $variation_ids ) ) {
WC()->cart->add_to_cart(111);
}
else {
//Do something
}
}
I am trying to pass the total amount of the cart ($GetTotalPrice) from function cart_prices_GetPrice() to function cart_prices_ApplyPrice(), using a woocommerce_after_calculate_totals and woocommerce_before_calculate_totals hooks, but I get an empty value.
//Trying to get cart amount
add_action('woocommerce_after_calculate_totals', 'cart_prices_GetPrice');
function cart_prices_GetPrice() {
//Getting the cart amount
$GetTotalPrice = WC()->cart->get_cart_total();
return $GetTotalPrice;
}
//Applying custom price
add_action('woocommerce_before_calculate_totals', 'cart_prices_ApplyPrice');
function cart_prices_ApplyPrice( $cart_object ) {
//Getting the cart amount from first function
$totalprice = cart_prices_GetPrice(); // doesn't work and returns 0 :(
//price change to cost2
if( $totalprice != 0 && $totalprice >= 2000 ) {
foreach ( $cart_object->get_cart() as $cart_id => $cart_item ) {
// get products id
$product_id = $cart_item['product_id'];
if( $cart_item['product_id'] == $product_id ) {
// price change to cost2
$new_price1 = 0.20;
$cart_item['data']->set_price( $new_price1 );
}
}
}
}
At the same time, each of the functions separately works perfectly.
What am I doing wrong? Is it possible to somehow link two hook data so that the first one doesn't return an empty value?
Update:
I will not be able to refuse the hook woocommerce_before_calculate_totals, because I need to apply a separate price reduction for each product in the cart.
You can simply not use cart total in woocommerce_before_calculate_totals when you want to alter cart item price for many reasons…
Instead you will get cart item subtotal inside woocommerce_before_calculate_totals hook. On the code below I use the discounted cart item subtotal including taxes:
add_action('woocommerce_before_calculate_totals', 'customize_cart_item_prices');
function customize_cart_item_prices( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding the hook repetition for price calculations
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$threshold_amount = 1000; // Min subtotal
$discount_rate = 0.2; // price discount rate (20%)
$cart_items = $cart->get_cart();
// Getting non discounted cart items subtotal
$subtotal_excl_tax = array_sum( wp_list_pluck( $cart_items, 'line_subtotal' ) );
$subtotal_tax = array_sum( wp_list_pluck( $cart_items, 'line_subtotal_tax' ) );
// Getting discounted cart items subtotal
$total_excl_tax = array_sum( wp_list_pluck( $cart_items, 'line_total' ) );
$total_tax = array_sum( wp_list_pluck( $cart_items, 'line_tax' ) );
if( ( $total_excl_tax + $total_tax ) >= $threshold_amount ) {
// Loop through cart items
foreach ( $cart_items as $item ) {
$price = $item['data']->get_price(); // Get price
$item['data']->set_price( $price * ( 1 - $discount_rate ) ); // Set new price
}
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
See on Change cart item prices in Woocommerce 3 answer code, to see how to handle minicart displayed custom cart item price.
Description:
I have use case where I need to check if a specific product has been added to cart before customer adds another products to cart.
Background:
We are renting products out based on packages(which are products). Packages include multiple products and products do not have price, packages do. So basically you would need to add a package(with price) and products(with no price) to cart.
Problem:
At the moment customers can add products before packages and they can continue to shopping cart with total zero.
Some of the progress what I have:
if ( ! WC()->cart->is_empty() )
foreach( WC()->cart->get_cart() as $cart_item )
// now i would need to check if cart consists a package
And i could solve adding product to cart with no package in cart like this:
if (WC()->cart->is_empty() )
//then don't add product to cart, tell customer to add package first.
Use the woocommerce_add_to_cart_validation hook
Comment with explanation added in the code
function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
// Product (ID) in cart
$product_first_in_cart = 30;
// Compare
if ( $product_first_in_cart != $product_id ) {
// Set variable
$in_cart = false;
// Cart NOT empty
if ( ! WC()->cart->is_empty() ) {
// Loop trough cart
foreach( WC()->cart->get_cart() as $cart_item ) {
// Search for the specific product
if ( $cart_item['data']->get_id() == $product_first_in_cart ) {
// Found, break loop
$in_cart = true;
break;
}
}
}
// NOT in cart
if ( ! $in_cart ) {
wc_add_notice( __( 'Please add product "A" before adding other products', 'woocommerce' ), 'error' );
$passed = false;
}
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );
I have tried a lot to override the existing product quantity in the cart but nothing.
Actually I have this code:
add_action('woocommerce_add_to_cart', 'add_to_cart_qty', 10, 6 );
function add_to_cart_qty( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ){
$real_product_id = $variation_id > 0 ? $variation_id : $product_id;
$product = wc_get_product($real_product_id);
$product_stock = $product->get_stock_quantity();
// Zero or negative stock (remove the product)
if( $product_stock <= 0 && $product->get_manage_stock() ){
WC()->cart->remove_cart_item( $cart_item_key );
return;
}
if( $quantity > $product_stock && $product->get_manage_stock() ){
WC()->cart->set_quantity( $cart_item_key, $product_stock );
}
}
that sets the maximum available product quantity when product is added to cart.
But I will need also to act in cart page when customer change the item quantities…
I think we can handle this issue in two ways:
first either we remove the product on add to the cart of the same product which is already in cart
second way is update the quantity of existing product on add to the cart of the same product, and this should also work for variable products.
I have tried a lot of different snippet codes for this but no results.
Any help will be appreciated.
Using this custom function hooked in woocommerce_after_cart_item_quantity_update action hook, will avoid customer to add more than the product stock quantity when updating cart item quantity:
add_action('woocommerce_after_cart_item_quantity_update', 'update_cart_items_quantities', 10, 4 );
function update_cart_items_quantities( $cart_item_key, $quantity, $old_quantity, $cart ){
$cart_data = $cart->get_cart();
$cart_item = $cart_data[$cart_item_key];
$manage_stock = $cart_item['data']->get_manage_stock();
$product_stock = $cart_item['data']->get_stock_quantity();
// Zero or negative stock (remove the product)
if( $product_stock <= 0 && $manage_stock ){
unset( $cart->cart_contents[ $cart_item_key ] );
}
if( $quantity > $product_stock && $manage_stock ){
$cart->cart_contents[ $cart_item_key ]['quantity'] = $product_stock;
}
return $product_stock;
}
Code goes in function.php file of your active child theme (or active theme) or in any plugin file.
This code is tested and works even for product variations.
My WordPresss related task is simple, but I can't find the solution. I have 2 products in my woocommerce shop, and I would like to show both of them on the cart-page in the woocommerce table, let the customer set the quantity of them. If the customer don't want to buy something, just leave it on 0.
The problem is the cart table is not shown if it is empty and I can only see the items that I put in there.
you can add product like that and add condition according you i set for admin and product id. change product id with your product id
/*
* goes in theme functions.php or a custom plugin
**/
// add item to cart on visit
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 64;
$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->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}