How to Set Discount Based on Quantity in WooCommerce?

Discount Based on Quantity

<?php
/**
* Discount based on the quantity.
* Type : Per Quantity, Fixed Price, Percentage
*/
function wc_before_calculate_totals_callback( $cart_object ) {
$quantity_price = array(
'2' => '90', // 10% discount for 2 qty
'3' => '85', // 15% discount for 3 qty
'4' => '80', // 20% discount for 4 qty
'8' => '75', // 25% discount for 8 qty
'9' => '72', // 28% discount for 9 and more qty
);
$quantity_price_keys = array_keys( $quantity_price );
$quantity_price_size = sizeof( $quantity_price_keys );
$quantity_min = min( $quantity_price_keys );
$type = 'percent'; // per_qty or fixed or percent
foreach ( $cart_object->get_cart() as $hash => $value ) {
$quantity = $value['quantity'];
if ( $quantity >= $quantity_min ) {
$closest_qty = wc_find_closest( $quantity_price_keys, $quantity_price_size, $quantity );
switch ( $type ) {
case 'per_qty':
$value['data']->set_price( $quantity_price[ $closest_qty ] );
break;
case 'fixed':
$value['data']->set_price( $quantity_price[ $closest_qty ] / $quantity );
break;
case 'percent':
$price = $value['data']->get_price();
$new_price = $price * ( $quantity_price[ $closest_qty ] / 100 );
$value['data']->set_price( $new_price );
break;
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'wc_before_calculate_totals_callback', 20, 1 );
/* Function to find closest quantity */
function wc_find_closest( $arr, $n, $target ) {
// Corner cases
if ( $target <= $arr[0] )
return $arr[0];
if ( $target >= $arr[$n - 1] )
return $arr[$n - 1];
// Doing binary search
$i = 0;
$j = $n;
$mid = 0;
while ( $i < $j ) {
$mid = ($i + $j) / 2;
if ( $arr[$mid] == $target )
return $arr[$mid];
if ( $target < $arr[ $mid ] ) {
if ( $mid > 0 && $target > $arr[ $mid - 1 ] )
return wc_get_closest( $arr[ $mid - 1 ], $arr[ $mid ], $target );
/* Repeat for left half */
$j = $mid;
} else { // If target is greater than mid
if ( $mid < $n - 1 && $target < $arr[ $mid + 1 ] )
return wc_get_closest( $arr[$mid], $arr[ $mid + 1 ], $target );
// update i
$i = $mid + 1;
}
}
// Only single element left after search
return $arr[$mid];
}
/* Function to get closest quantity */
function wc_get_closest( $val1, $val2, $target ) {
if ( $target - $val1 >= $val2 - $target )
return $val2;
else
return $val1;
}
view raw functions.php hosted with ❤ by GitHub

Leave a Reply