fix endless loop of death
This commit is contained in:
parent
6a9e612a83
commit
2b9e3aafdd
|
@ -51,6 +51,8 @@ class WC_Discounts {
|
|||
* @param array $raw_items List of raw cart or order items.
|
||||
*/
|
||||
public function set_items( $raw_items ) {
|
||||
$this->items = array();
|
||||
|
||||
if ( ! empty( $raw_items ) && is_array( $raw_items ) ) {
|
||||
foreach ( $raw_items as $raw_item ) {
|
||||
$item = (object) array(
|
||||
|
@ -117,8 +119,11 @@ class WC_Discounts {
|
|||
case 'percent' :
|
||||
$this->apply_percentage_discount( $amount );
|
||||
break;
|
||||
case 'fixed' :
|
||||
$this->apply_fixed_discount( $amount );
|
||||
case 'fixed_product' :
|
||||
$this->apply_fixed_product_discount( $amount );
|
||||
break;
|
||||
case 'fixed_cart' :
|
||||
$this->apply_fixed_cart_discount( $amount );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -137,25 +142,44 @@ class WC_Discounts {
|
|||
}
|
||||
|
||||
/**
|
||||
* Apply fixed discount to items.
|
||||
* Apply fixed product discount to items.
|
||||
*
|
||||
* @param float $amount
|
||||
*/
|
||||
private function apply_fixed_discount( $total_amount ) {
|
||||
private function apply_fixed_product_discount( $discount ) {
|
||||
foreach ( $this->items as $item ) {
|
||||
$item->discounted_price -= $discount;
|
||||
$item->discounted_price = max( 0, $item->discounted_price );
|
||||
}
|
||||
}
|
||||
|
||||
private function apply_discount_to_item( &$item, $discount ) {
|
||||
if ( $discount > $item->discounted_price ) {
|
||||
$discount = $item->discounted_price;
|
||||
}
|
||||
$item->discounted_price = $item->discounted_price - $discount;
|
||||
return $discount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply fixed cart discount to items.
|
||||
*
|
||||
* @param float $amount
|
||||
*/
|
||||
private function apply_fixed_cart_discount( $total_amount ) {
|
||||
// Fixed amount needs to be divided equally between items.
|
||||
$item_count = array_sum( wp_list_pluck( $this->items, 'quantity' ) );
|
||||
$discount = floor( $total_amount / $item_count );
|
||||
$discounted = 0; // Keep track of what actually gets discounted, since some products may be cheaper than the discount.
|
||||
|
||||
if ( $discount ) {
|
||||
if ( 0 < $discount ) {
|
||||
foreach ( $this->items as $item ) {
|
||||
$discounted += min( $discount, $item->discounted_price );
|
||||
$item->discounted_price -= $discount;
|
||||
$discounted += $this->apply_discount_to_item( $item, $discount );
|
||||
}
|
||||
|
||||
// Anything left?
|
||||
if ( $remaining_discount = $total_amount - $discounted ) {
|
||||
$this->apply_fixed_discount( $remaining_discount );
|
||||
if ( $discounted && ( $remaining_discount = $total_amount - $discounted ) ) {
|
||||
$this->apply_fixed_cart_discount( $remaining_discount );
|
||||
}
|
||||
|
||||
// Amount is too small to divide equally.
|
||||
|
|
|
@ -56,6 +56,7 @@ class WC_Tests_Discounts extends WC_Unit_Test_Case {
|
|||
|
||||
// Create dummy content.
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
WC()->cart->empty_cart();
|
||||
WC()->cart->add_to_cart( $product->get_id(), 1 );
|
||||
$coupon = new WC_Coupon;
|
||||
$coupon->set_code( 'test' );
|
||||
|
@ -68,13 +69,14 @@ class WC_Tests_Discounts extends WC_Unit_Test_Case {
|
|||
$discounts->apply_coupon( $coupon );
|
||||
$this->assertEquals( array( (object) array( 'price' => '10', 'discounted_price' => '8', 'quantity' => 1 ) ), $discounts->get_items() );
|
||||
|
||||
// Apply a fixed coupon.
|
||||
$coupon->set_discount_type( 'fixed' );
|
||||
// Apply a fixed cart coupon.
|
||||
$coupon->set_discount_type( 'fixed_cart' );
|
||||
$discounts->set_items( WC()->cart->get_cart() );
|
||||
$discounts->apply_coupon( $coupon );
|
||||
var_dump($discounts->get_items());
|
||||
$this->assertEquals( array( (object) array( 'price' => '10', 'discounted_price' => '0', 'quantity' => 1 ) ), $discounts->get_items() );
|
||||
|
||||
// Apply a fixed coupon.
|
||||
// Apply a fixed cart coupon.
|
||||
$coupon->set_discount_type( 'fixed_cart' );
|
||||
WC()->cart->empty_cart();
|
||||
WC()->cart->add_to_cart( $product->get_id(), 4 );
|
||||
|
@ -82,6 +84,15 @@ class WC_Tests_Discounts extends WC_Unit_Test_Case {
|
|||
$discounts->apply_coupon( $coupon );
|
||||
$this->assertEquals( array( (object) array( 'price' => '40', 'discounted_price' => '20', 'quantity' => 4 ) ), $discounts->get_items() );
|
||||
|
||||
// Apply a fixed product coupon.
|
||||
$coupon->set_discount_type( 'fixed_product' );
|
||||
$coupon->set_amount( 1 );
|
||||
WC()->cart->empty_cart();
|
||||
WC()->cart->add_to_cart( $product->get_id(), 4 );
|
||||
$discounts->set_items( WC()->cart->get_cart() );
|
||||
$discounts->apply_coupon( $coupon );
|
||||
$this->assertEquals( array( (object) array( 'price' => '40', 'discounted_price' => '36', 'quantity' => 4 ) ), $discounts->get_items() );
|
||||
|
||||
// Cleanup.
|
||||
WC()->cart->empty_cart();
|
||||
$product->delete( true );
|
||||
|
|
Loading…
Reference in New Issue