WIP
This commit is contained in:
parent
1881b590d5
commit
2255066c0f
|
@ -72,12 +72,13 @@ class WC_Discounts {
|
|||
$item->key = $key;
|
||||
$item->object = $cart_item;
|
||||
$item->product = $cart_item['data'];
|
||||
$item->quantity = $cart_item['quantity'];
|
||||
$item->price = wc_add_number_precision_deep( $item->product->get_price() ) * $item->quantity;
|
||||
$this->items[ $key ] = $item;
|
||||
}
|
||||
$item->price = wc_add_number_precision_deep( $item->product->get_price() );
|
||||
|
||||
uasort( $this->items, array( $this, 'sort_by_price' ) );
|
||||
for ( $i = 0; $i < $cart_item['quantity']; $i ++ ) {
|
||||
$this->items[ $key . ':' . $i ] = clone $item;
|
||||
$this->items[ $key . ':' . $i ]->index = $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,14 +136,22 @@ class WC_Discounts {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all discount totals.
|
||||
* Get all discount totals for line items.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @param bool $in_cents Should the totals be returned in cents, or without precision.
|
||||
* @return array
|
||||
*/
|
||||
public function get_discounts( $in_cents = false ) {
|
||||
$discounts = $this->discounts;
|
||||
$discounts = array();
|
||||
|
||||
foreach ( $this->discounts as $coupon_code => $coupon_discounts ) {
|
||||
foreach ( $coupon_discounts as $key => $discount ) {
|
||||
$line_item_key = current( explode( ':', $key ) );
|
||||
$discounts[ $coupon_code ][ $line_item_key ] = isset( $discounts[ $coupon_code ], $discounts[ $coupon_code ][ $line_item_key ] ) ? $discounts[ $coupon_code ][ $line_item_key ] + $discount : $discount;
|
||||
}
|
||||
}
|
||||
|
||||
return $in_cents ? $discounts : wc_remove_number_precision_deep( $discounts );
|
||||
}
|
||||
|
||||
|
@ -154,16 +163,16 @@ class WC_Discounts {
|
|||
* @return array
|
||||
*/
|
||||
public function get_discounts_by_item( $in_cents = false ) {
|
||||
$discounts = $this->discounts;
|
||||
$item_discount_totals = (array) array_shift( $discounts );
|
||||
$discounts = array();
|
||||
|
||||
foreach ( $discounts as $item_discounts ) {
|
||||
foreach ( $item_discounts as $item_key => $item_discount ) {
|
||||
$item_discount_totals[ $item_key ] += $item_discount;
|
||||
foreach ( $this->discounts as $coupon_code => $coupon_discounts ) {
|
||||
foreach ( $coupon_discounts as $key => $discount ) {
|
||||
$line_item_key = current( explode( ':', $key ) );
|
||||
$discounts[ $line_item_key ] = isset( $discounts[ $line_item_key ] ) ? $discounts[ $line_item_key ] + $discount : $discount;
|
||||
}
|
||||
}
|
||||
|
||||
return $in_cents ? $item_discount_totals : wc_remove_number_precision_deep( $item_discount_totals );
|
||||
return $in_cents ? $discounts : wc_remove_number_precision_deep( $discounts );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +207,7 @@ class WC_Discounts {
|
|||
* @return int
|
||||
*/
|
||||
public function get_discounted_price_in_cents( $item ) {
|
||||
return absint( $item->price - $this->get_discount( $item->key, true ) );
|
||||
return absint( $item->price - $this->get_discount( $item->key . ':' . $item->index, true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,14 +248,14 @@ class WC_Discounts {
|
|||
$this->apply_coupon_fixed_cart( $coupon, $items_to_apply );
|
||||
break;
|
||||
default :
|
||||
foreach ( $items_to_apply as $item ) {
|
||||
foreach ( $items_to_apply as $key => $item ) {
|
||||
$discounted_price = $this->get_discounted_price_in_cents( $item );
|
||||
$price_to_discount = wc_remove_number_precision( ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price );
|
||||
$discount = wc_add_number_precision( $coupon->get_discount_amount( $price_to_discount, $item->object ) ) * $item->quantity;
|
||||
$discount = min( $discounted_price, $discount );
|
||||
|
||||
// Store code and discount amount per item.
|
||||
$this->discounts[ $coupon->get_code() ][ $item->key ] += $discount;
|
||||
$this->discounts[ $coupon->get_code() ][ $key ] += $discount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -263,12 +272,14 @@ class WC_Discounts {
|
|||
* @return int
|
||||
*/
|
||||
protected function sort_by_price( $a, $b ) {
|
||||
$price_1 = $a->price * $a->quantity;
|
||||
$price_2 = $b->price * $b->quantity;
|
||||
$price_1 = $this->get_discounted_price_in_cents( $a );
|
||||
$price_2 = $this->get_discounted_price_in_cents( $b );
|
||||
var_dump($price_1);var_dump($price_2);
|
||||
if ( $price_1 === $price_2 ) {
|
||||
return 0;
|
||||
}
|
||||
return ( $price_1 < $price_2 ) ? 1 : -1;
|
||||
|
||||
return ( $price_1 > $price_2 ) ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,12 +310,15 @@ class WC_Discounts {
|
|||
$limit_usage_qty = $coupon->get_limit_usage_to_x_items();
|
||||
}
|
||||
|
||||
foreach ( $this->items as $item ) {
|
||||
uasort( $this->items, array( $this, 'sort_by_price' ) );
|
||||
|
||||
foreach ( $this->items as $key => $item ) {
|
||||
$item_to_apply = clone $item; // Clone the item so changes to this item do not affect the originals.
|
||||
|
||||
if ( 0 === $this->get_discounted_price_in_cents( $item_to_apply ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $coupon->is_valid_for_product( $item_to_apply->product, $item_to_apply->object ) && ! $coupon->is_valid_for_cart() ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -312,20 +326,11 @@ class WC_Discounts {
|
|||
if ( $limit_usage_qty && $applied_count >= $limit_usage_qty ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $limit_usage_qty && $item_to_apply->quantity > ( $limit_usage_qty - $applied_count ) ) {
|
||||
$limit_to_qty = absint( $limit_usage_qty - $applied_count );
|
||||
|
||||
// Lower the qty and cost so the discount is applied less.
|
||||
$item_to_apply->price = ( $item_to_apply->price / $item_to_apply->quantity ) * $limit_to_qty;
|
||||
$item_to_apply->quantity = $limit_to_qty;
|
||||
}
|
||||
if ( 0 >= $item_to_apply->quantity ) {
|
||||
continue;
|
||||
}
|
||||
$items_to_apply[] = $item_to_apply;
|
||||
$applied_count += $item_to_apply->quantity;
|
||||
echo $key . ' ';
|
||||
$items_to_apply[ $key ] = $item_to_apply;
|
||||
$applied_count = $applied_count + 1;
|
||||
}
|
||||
|
||||
return $items_to_apply;
|
||||
}
|
||||
|
||||
|
@ -344,7 +349,7 @@ class WC_Discounts {
|
|||
// Because get_amount() could return an empty string, let's be sure to set our local variable to a known good value.
|
||||
$coupon_amount = ( '' === $coupon->get_amount() ) ? 0 : $coupon->get_amount();
|
||||
|
||||
foreach ( $items_to_apply as $item ) {
|
||||
foreach ( $items_to_apply as $key => $item ) {
|
||||
// Find out how much price is available to discount for the item.
|
||||
$discounted_price = $this->get_discounted_price_in_cents( $item );
|
||||
|
||||
|
@ -367,7 +372,7 @@ class WC_Discounts {
|
|||
$total_discount += $discount;
|
||||
|
||||
// Store code and discount amount per item.
|
||||
$this->discounts[ $coupon->get_code() ][ $item->key ] += $discount;
|
||||
$this->discounts[ $coupon->get_code() ][ $key ] += $discount;
|
||||
}
|
||||
|
||||
// Work out how much discount would have been given to the cart as a whole and compare to what was discounted on all line items.
|
||||
|
@ -390,10 +395,10 @@ class WC_Discounts {
|
|||
* @return int Total discounted.
|
||||
*/
|
||||
protected function apply_coupon_fixed_product( $coupon, $items_to_apply, $amount = null ) {
|
||||
$total_discount = 0;
|
||||
$amount = $amount ? $amount : wc_add_number_precision( $coupon->get_amount() );
|
||||
$total_discount = 0;
|
||||
$amount = $amount ? $amount: wc_add_number_precision( $coupon->get_amount() );
|
||||
|
||||
foreach ( $items_to_apply as $item ) {
|
||||
foreach ( $items_to_apply as $key => $item ) {
|
||||
// Find out how much price is available to discount for the item.
|
||||
$discounted_price = $this->get_discounted_price_in_cents( $item );
|
||||
|
||||
|
@ -401,7 +406,7 @@ class WC_Discounts {
|
|||
$price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price;
|
||||
|
||||
// Run coupon calculations.
|
||||
$discount = $amount * $item->quantity;
|
||||
$discount = $amount;
|
||||
|
||||
if ( is_a( $this->object, 'WC_Cart' ) && has_filter( 'woocommerce_coupon_get_discount_amount' ) ) {
|
||||
// Send through the legacy filter, but not as cents.
|
||||
|
@ -412,7 +417,7 @@ class WC_Discounts {
|
|||
$total_discount += $discount;
|
||||
|
||||
// Store code and discount amount per item.
|
||||
$this->discounts[ $coupon->get_code() ][ $item->key ] += $discount;
|
||||
$this->discounts[ $coupon->get_code() ][ $key ] += $discount;
|
||||
}
|
||||
return $total_discount;
|
||||
}
|
||||
|
@ -469,8 +474,8 @@ class WC_Discounts {
|
|||
*/
|
||||
protected function apply_coupon_remainder( $coupon, $items_to_apply, $amount ) {
|
||||
$total_discount = 0;
|
||||
|
||||
foreach ( $items_to_apply as $item ) {
|
||||
return;
|
||||
foreach ( $items_to_apply as $key => $item ) {
|
||||
for ( $i = 0; $i < $item->quantity; $i ++ ) {
|
||||
// Find out how much price is available to discount for the item.
|
||||
$discounted_price = $this->get_discounted_price_in_cents( $item );
|
||||
|
@ -485,7 +490,7 @@ class WC_Discounts {
|
|||
$total_discount += $discount;
|
||||
|
||||
// Store code and discount amount per item.
|
||||
$this->discounts[ $coupon->get_code() ][ $item->key ] += $discount;
|
||||
$this->discounts[ $coupon->get_code() ][ $key ] += $discount;
|
||||
|
||||
if ( $total_discount >= $amount ) {
|
||||
break 2;
|
||||
|
|
Loading…
Reference in New Issue