I need to add discount according to number of product in cart and this discount will apply on total of cart. Is there any other option without use of coupons?
I prefer this way, cleaner I think
// Hook before calculate fees
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
/**
* Add custom fee if more than three article
* #param WC_Cart $cart
*/
function add_custom_fees( WC_Cart $cart ){
if( $cart->cart_contents_count < 3 ){
return;
}
// Calculate the amount to reduce
$discount = $cart->subtotal * 0.1;
$cart->add_fee( 'You have more than 3 items in your cart, a 10% discount has been added.', -$discount);
}
This code should work:
add_action('woocommerce_before_cart_table', 'discount_when_produts_in_cart');
function discount_when_produts_in_cart( ) {
global $woocommerce;
if( $woocommerce->cart->cart_contents_count > 3 ) {
$coupon_code = 'maryscode';
if (!$woocommerce->cart->add_discount( sanitize_text_field( $coupon_code ))) {
$woocommerce->show_messages();
}
echo '<div class="woocommerce_message"><strong>You have more than 3 items in your cart, a 10% discount has been added.</strong></div>';
}
}
The above will apply the coupon "maryscode" to the cart if there are 4 or more products in the customers cart.
EDIT: Add the following to your css
.coupon {
display: none !important;
}
Related
I am trying to hide a specific class when cart subtotal on Woocommerce is above a certain amount.
I have used the code below but have not achieved anything yet. Thank you in advance.
add_filter( 'woocommerce_package_rates', 'hide_specific_class', 10, 2 );
function hide_specific_class($classes, $package ) {
$cart_subtotal = WC()->cart->get_subtotal();
if ( $cart_subtotal > 20 ) {
unset($classes[array_search('inactive-shipping', $classes)]);
return $classes;
}
}
`
The following working code is a discount for cart with minimum 3 items not including 'sale' products Now I need to ignore categoty 'gift' (if it is in the cart) from this discount:
//10% discount at minimum 3 items in cart not for sale items
add_action('woocommerce_cart_calculate_fees' , 'custom_cart_discount', 20, 1);
function custom_cart_discount( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Limitations: Only when there is 5 or more non on sale items in cart
$starting_limit = 3;
// Initialising variables
$not_on_sale_subtotal = $discount = $items_count = 0;
// Iterating through each item in cart
foreach( $cart->get_cart() as $cart_item ){
// For cart items is not on sale
if( ! $cart_item['data']->is_on_sale() ){
$not_on_sale_subtotal += (float) $cart_item['line_subtotal'];
$items_count += $cart_item['quantity'];
}
}
// Discount calculation
$discount = $not_on_sale_subtotal * 0.1;
// Applied discount only cart items that are not on sale
if( $discount && $items_count >= $starting_limit )
$cart->add_fee( 'הנחת כמות 10%', -$discount );
I would recommend to work with a different approach. WooCommerce Coupons gives you a full control for what you want to achieve.
First, create a coupon in WC admin, with the 10% discount. Then, use the coupon settings to apply it on the cart or just on specific items/categories. You can see in the coupon limitations how exactly to limit the discount to specific categories (with include / exclude ), or to apply the discount only on items that are not on sale etc...
Finally, all you have to do, is just to ask or encourage the customer to apply the coupon, or automatically apply it yourself behind the scenes with:
WC()->cart->apply_coupon('YouCouponCodeGoesHere');
בהצלחה!
For a client, I need to let backorders for products but they don't want to charge for those. So, I need to update the price dynamically if they stock is 0 or the stock is less than the quantity on the cart.
This is my code:
add_filter( 'woocommerce_cart_product_subtotal', 'modify_cart_product_subtotal', 10, 4 );
function modify_cart_product_subtotal( $product_subtotal, $product, $quantity, $cart ) {
if ( $product->get_stock_quantity() < $quantity ) {
return $product->get_stock_quantity() * $product->get_price();
}
return $product_subtotal;
}
In case of 0 stock, it works like a charm. In case of a quantity greater than the stock, it charges only for the available products, but the tax keeps increasing even for the rest. How can I exclude those from taxes calculations as well?
EDIT:
If I just update the price of the product, it does it for all of them, not only those above the available stock.
function zero_price_for_backorders( $cart_object ) {
global $isProcessed;
if( !WC()->session->__isset( "reload_checkout" )) {
foreach ( $cart_object->get_cart() as $key => $value ) {
if ( $value['data']->get_stock_quantity() < $value['quantity']) {
$value['data']->set_price(0);
}
}
$isProcessed = true;
}
}
add_action( 'woocommerce_before_calculate_totals', 'zero_price_for_backorders', 99 );
You should use before_calculate_total and change product price using set_price function so that you don't have to modify subtotal separately. The rest of the flow will fall in place automatically.
You can have a look at this link on how to change it dynamically:
Change product price dynamically woocommerce
I want to apply the discount coupon to the specific product in cart from checkout page.
Inside the cart:
product1 w/ upgrades
product2 w/o upgrades
when I apply the discount coupon I want that the discount will take effect only in product2's price. I tried to search in some forums but the coupon will take effect in the whole cart items.
You can try this piece of code:
function calculate_variation_addon_price( $cart_object ) {
global $isProcessed;
// Loop for all products in cart
foreach ( $cart_object->cart_contents as $key => $value ) {
// Your condition here for product specific i.e. id == 25
if((!isset($isProcessed) || empty($isProcessed))) {
$orgPrice = floatval( $value['data']->get_price() );
$cart_object->cart_contents[$key]['data']->set_price( $orgPrice * 0.5 );
}
}
$isProcessed = 1;
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_variation_addon_price', 2, 1 );
While adding coupon from admin panel, find a tab there, called 'Usage Restriction'.
There you can add products or product categories or even exclude some for the coupon code to be applied.
You can so that using product id, sku or name
function filter_woocommerce_coupon_get_discount_amount( $discounting_amount, $price_to_discount , $cart_item, $single, $coupon ) {
// On backorder
if ( $cart_item['data']->get_id() !== 'product2_id' ) {
$discounting_amount = 0;
}
return $discounting_amount;
}
add_filter( 'woocommerce_coupon_get_discount_amount', 'filter_woocommerce_coupon_get_discount_amount', 10, 5 );
You can use in_array instead of !== for multiple products
You also replace get_id() by other properties or use custom attributs...
I found this answer in a earlier post here (below), but I want to know of there is any way to add an extra fee based on quantity if the product quantity changes?
Lets say there is 100 items in one package. (the problem is also that there is not they same amount of item in all packages, some can be 100, some can be 150, 200, or 500)
Example:
1-99 = 1$.
100 = no fee.
101 - 199 1$
200 = no fee
201 - 299 = 1$ and so on..
Total will always be 1$ per product but the total can be more if they order several products that have these breaks. The total can be 4$ if there is 4 products with break-cost.
(Also, not sure where to put the code)
Thank you!
The code I found here: Add additional costs based on quantity in Woocommerce
// Hook before adding fees
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
/**
* Add custom fee on article specifics
* #param WC_Cart $cart
*/
function add_custom_fees( WC_Cart $cart ){
$fees = 0;
foreach( $cart->get_cart() as $item ){
// Check if odds and if it's the right item
if( $item[ 'quantity' ] % 2 == 1 && get_post_meta( $item[ 'product_id' ], 'custom_fee_for_supplier_name', true) ){
// You can also put a custom price in each produt with get_post_meta
$fees += 10;
}
}
if( $fees != 0 ){
// You can customize the descriptions here
$cart->add_fee( 'Custom fee (odds paquets)', $fees);
}
}
The woocommerce_after_cart_item_quantity_update fires right after a quantity is updated. If you modify your function a little bit (to use WC()->cart to access the cart object) you can run the same function on both hooks. I thought it might keep adding additional fees, but in my testing it seems to just recalculate the right cost for the same fee.
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
add_action( 'woocommerce_after_cart_item_quantity_update', 'add_custom_fees' );
/**
* Add custom fee on article specifics
* #param WC_Cart $cart
*/
function add_custom_fees(){
$fees = 0;
foreach( WC()->cart->get_cart() as $item ){
// Check if odds and if it's the right item
if( $item[ 'quantity' ] % 2 == 1 && get_post_meta( $item[ 'product_id' ], '_custom_fee_for_odds', true ) ){
// You can also put a custom price in each produt with get_post_meta
$fees += 10;
}
}
if( $fees > 0 ){
// You can customize the descriptions here
WC()->cart->add_fee( 'Custom fee (odds paquets)', $fees);
}
}