I am using the following code that applies progressive discounts based on order amount.
add_action('woocommerce_cart_calculate_fees', 'woo_discount_total');
function woo_discount_total(WC_Cart $cart) {
if( is_admin() && !defined('DOING_AJAX') ) {
return;
}
$woo_current_price = $cart->subtotal;
if($woo_current_price >= 3000 && $woo_current_price <= 9990) {
$discount = $cart->subtotal * 0.02; // 0.02 = 2%
$cart->add_fee('Sale 2% ', -$discount);
}
elseif($woo_current_price >= 10000) {
$discount = $cart->subtotal * 0.05; // 0.05 = 5%
$cart->add_fee('Sale 5% ', -$discount);
}
}
But there is a problem. If there is a product on sale with a 15% discount in the cart, then all discounts are summed.
As far as I understand, I need to spell out the conditions?
What I would like is:
How can this be implemented?
A discounted item could be:
In the code below I have implemented both, so if a coupon is applied or if there is an "on sale" item, Your custom progressive discount based on cart subtotal will not be applied.
Try:
// Conditional function that check if there are cart items "on sale"
function has_items_on_sale( $cart ) {
// Loop through cart items
foreach ( $cart->get_cart() as $item ) {
if ( $item['data']->is_on_sale() ) {
return true;
}
}
return false;
}
// Progressive discount based on cart subtotal
add_action( 'woocommerce_cart_calculate_fees', 'subtotal_based_progressive_discount' );
function subtotal_based_progressive_discount( $cart ) {
if( is_admin() && !defined('DOING_AJAX') ) {
return;
}
// Exit if a cart item is on sale
if( has_items_on_sale( $cart ) ) {
return;
}
// Exit if a coupon has been applied to cart
if( $cart->get_applied_coupons() ) {
return;
}
$subtotal = $cart->subtotal;
$percent = 0;
if( $subtotal >= 3000 && $subtotal < 10000 ) {
$percent = 2; // 2 %
} elseif( $subtotal >= 10000 ) {
$percent = 5; // 5 %
}
if( $percent > 0 ) {
$cart->add_fee( __('Sale') . " {$percent}%", -($subtotal * $percent / 100) );
}
}
It should work.
Alternatively, you can use the following to apply a progressive discount on the subtotal excluding "on sale" items (if there is no applied coupons):
// Utility function: Get cart subtotal excluding on sale items
function get_subtotal_excluding_on_sale_items( $cart, $subtotal = 0 ) {
// Loop through cart items
foreach ( $cart->get_cart() as $item ) {
if ( ! $item['data']->is_on_sale() ) {
$subtotal = $item['line_subtotal'] + $item['line_subtotal_tax'];
}
}
return $subtotal;
}
// Progressive discount based on cart subtotal
add_action( 'woocommerce_cart_calculate_fees', 'subtotal_based_progressive_discount' );
function subtotal_based_progressive_discount( $cart ) {
if( is_admin() && !defined('DOING_AJAX') ) {
return;
}
// Exit if a coupon has been applied to cart (optional)
if( $cart->get_applied_coupons() ) {
return;
}
$subtotal = get_subtotal_excluding_on_sale_items( $cart );
$percent = 0;
if( $subtotal >= 3000 && $subtotal < 10000 ) {
$percent = 2; // 2 %
} elseif( $subtotal >= 10000 ) {
$percent = 5; // 5 %
}
if( $percent > 0 ) {
$cart->add_fee( __('Sale') . " {$percent}%", -($subtotal * $percent / 100) );
}
}
It should work.