Order subclass
This commit is contained in:
parent
250dabaf41
commit
1faae6a7aa
|
@ -17,8 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
* WC_Totals class.
|
||||
*
|
||||
* @todo woocommerce_tax_round_at_subtotal option - how should we handle this with precision?
|
||||
* @todo woocommerce_calculate_totals action for carts.
|
||||
* @todo woocommerce_calculated_total filter for carts.
|
||||
* @todo Manual discounts.
|
||||
* @since 3.2.0
|
||||
*/
|
||||
abstract class WC_Totals {
|
||||
|
@ -105,11 +104,11 @@ abstract class WC_Totals {
|
|||
* Sets up the items provided, and calculate totals.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @param object $cart Cart or order object to calculate totals for.
|
||||
* @param object $object Cart or order object to calculate totals for.
|
||||
*/
|
||||
public function __construct( &$cart = null ) {
|
||||
public function __construct( &$object = null ) {
|
||||
$this->precision = pow( 10, wc_get_price_decimals() );
|
||||
$this->object = $cart;
|
||||
$this->object = $object;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,6 +193,7 @@ abstract class WC_Totals {
|
|||
protected function get_default_item_props() {
|
||||
return (object) array(
|
||||
'key' => '',
|
||||
'object' => null,
|
||||
'quantity' => 0,
|
||||
'price' => 0,
|
||||
'product' => false,
|
||||
|
@ -433,9 +433,6 @@ abstract class WC_Totals {
|
|||
/**
|
||||
* Calculate all discount and coupon amounts.
|
||||
*
|
||||
* @todo Manual discounts.
|
||||
* @todo record coupon totals and counts for cart.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @uses WC_Discounts class.
|
||||
*/
|
||||
|
@ -496,7 +493,6 @@ abstract class WC_Totals {
|
|||
protected function calculate_totals() {
|
||||
$this->set_total( 'taxes', $this->get_merged_taxes() );
|
||||
$this->set_total( 'tax_total', array_sum( wp_list_pluck( $this->get_total( 'taxes', true ), 'tax_total' ) ) );
|
||||
$this->set_total( 'shipping_tax_total', array_sum( wp_list_pluck( $this->get_total( 'taxes', true ), 'shipping_tax_total' ) ) );
|
||||
$this->set_total( 'total', round( $this->get_total( 'items_total', true ) + $this->get_total( 'fees_total', true ) + $this->get_total( 'shipping_total', true ) + $this->get_total( 'tax_total', true ) + $this->get_total( 'shipping_tax_total', true ) ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
/**
|
||||
* WC_Cart_Totals class.
|
||||
*
|
||||
* @todo woocommerce_calculate_totals action for carts.
|
||||
* @todo woocommerce_calculated_total filter for carts.
|
||||
* @todo record coupon totals and counts for cart.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
final class WC_Cart_Totals extends WC_Totals {
|
||||
|
@ -24,12 +28,11 @@ final class WC_Cart_Totals extends WC_Totals {
|
|||
* Sets up the items provided, and calculate totals.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @param object $cart Cart or order object to calculate totals for.
|
||||
* @param object $object Cart or order object to calculate totals for.
|
||||
*/
|
||||
public function __construct( &$cart = null ) {
|
||||
parent::__construct( $cart );
|
||||
|
||||
if ( is_a( $cart, 'WC_Cart' ) ) {
|
||||
public function __construct( &$object = null ) {
|
||||
if ( is_a( $object, 'WC_Cart' ) ) {
|
||||
parent::__construct( $object );
|
||||
$this->calculate();
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +51,12 @@ final class WC_Cart_Totals extends WC_Totals {
|
|||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_items() {
|
||||
$this->items = array();
|
||||
|
||||
foreach ( $this->object->get_cart() as $cart_item_key => $cart_item ) {
|
||||
$item = $this->get_default_item_props();
|
||||
$item->key = $cart_item_key;
|
||||
$item->cart_item = $cart_item;
|
||||
$item->object = $cart_item;
|
||||
$item->quantity = $cart_item['quantity'];
|
||||
$item->price = $this->add_precision( $cart_item['data']->get_price() ) * $cart_item['quantity'];
|
||||
$item->product = $cart_item['data'];
|
||||
|
@ -93,9 +98,10 @@ final class WC_Cart_Totals extends WC_Totals {
|
|||
|
||||
foreach ( $this->object->calculate_shipping() as $key => $shipping_object ) {
|
||||
$shipping_line = $this->get_default_shipping_props();
|
||||
$shipping_line->object = $shipping_object;
|
||||
$shipping_line->total = $this->add_precision( $shipping_object->cost );
|
||||
$shipping_line->taxes = array_map( array( $this, 'add_precision' ), $shipping_object->taxes );
|
||||
$shipping_line->total_tax = array_sum( $shipping_object->taxes );
|
||||
$shipping_line->taxes = $this->add_precision( $shipping_object->taxes );
|
||||
$shipping_line->total_tax = $this->add_precision( array_sum( $shipping_object->taxes ) );
|
||||
$this->shipping[ $key ] = $shipping_line;
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +111,6 @@ final class WC_Cart_Totals extends WC_Totals {
|
|||
* into the same format for use by this class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @return array
|
||||
*/
|
||||
protected function set_coupons() {
|
||||
$this->coupons = $this->object->get_coupons();
|
||||
|
@ -160,9 +165,7 @@ final class WC_Cart_Totals extends WC_Totals {
|
|||
protected function calculate_totals() {
|
||||
parent::calculate_totals();
|
||||
|
||||
$this->object->total = $this->get_total( 'total' );
|
||||
$this->object->tax_total = $this->get_total( 'tax_total' );
|
||||
$this->object->shipping_total = $this->get_total( 'shipping_total' );
|
||||
$this->object->shipping_tax_total = $this->get_total( 'shipping_tax_total' );
|
||||
$this->object->tax_total = $this->get_total( 'tax_total' );
|
||||
$this->object->total = $this->get_total( 'total' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ class WC_Discounts {
|
|||
if ( 0 === $this->get_discounted_price_in_cents( $item ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! $coupon->is_valid_for_product( $item->product, $item->cart_item ) && ! $coupon->is_valid_for_cart() ) {
|
||||
if ( ! $coupon->is_valid_for_product( $item->product, $item->object ) && ! $coupon->is_valid_for_cart() ) {
|
||||
continue;
|
||||
}
|
||||
if ( $limit_usage_qty && $applied_count > $limit_usage_qty ) {
|
||||
|
@ -603,7 +603,7 @@ class WC_Discounts {
|
|||
$valid = false;
|
||||
|
||||
foreach ( $this->items as $item ) {
|
||||
if ( $item->product && $coupon->is_valid_for_product( $item->product, $item->cart_item ) ) {
|
||||
if ( $item->product && $coupon->is_valid_for_product( $item->product, $item->object ) ) {
|
||||
$valid = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,101 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
}
|
||||
|
||||
/**
|
||||
* WC_Order_Totals class. @todo this class needs writing.
|
||||
* WC_Order_Totals class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
final class WC_Order_Totals extends WC_Totals {}
|
||||
final class WC_Order_Totals extends WC_Totals {
|
||||
|
||||
/**
|
||||
* Sets up the items provided, and calculate totals.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @param object $object Cart or order object to calculate totals for.
|
||||
*/
|
||||
public function __construct( &$object = null ) {
|
||||
if ( is_a( $object, 'WC_Order' ) ) {
|
||||
parent::__construct( $object );
|
||||
$this->calculate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an order object passed in for calculation. Normalises data into the same format for use by this class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_items() {
|
||||
$this->items = array();
|
||||
|
||||
foreach ( $this->object->get_items() as $order_item_id => $order_item ) {
|
||||
$item = $this->get_default_item_props();
|
||||
$item->key = $order_item_id;
|
||||
$item->object = $order_item;
|
||||
$item->product = $order_item->get_product();
|
||||
$item->quantity = $order_item->get_quantity();
|
||||
$item->price = $this->add_precision( $order_item->get_subtotal() );
|
||||
$this->items[ $order_item_id ] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fee objects from the cart. Normalises data into the same format for use by this class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_fees() {
|
||||
$this->fees = array();
|
||||
|
||||
foreach ( $this->object->get_fees() as $fee_key => $fee_object ) {
|
||||
$fee = $this->get_default_fee_props();
|
||||
$fee->object = $fee_object;
|
||||
$fee->total = $this->add_precision( $fee_object->get_total() );
|
||||
$fee->taxes = $this->add_precision( $fee_object->get_taxes() );
|
||||
$fee->total_tax = $this->add_precision( $fee_object->get_total_tax() );
|
||||
$this->fees[ $fee_key ] = $fee;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping methods from the cart and normalise.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_shipping() {
|
||||
$this->shipping = array();
|
||||
|
||||
foreach ( $this->object->get_shipping_methods() as $key => $shipping_object ) {
|
||||
$shipping_line = $this->get_default_shipping_props();
|
||||
$shipping_line->object = $shipping_object;
|
||||
$shipping_line->total = $this->add_precision( $shipping_object->get_total() );
|
||||
$shipping_line->taxes = $this->add_precision( $shipping_object->get_taxes() );
|
||||
$shipping_line->total_tax = $this->add_precision( $shipping_object->get_total_tax() );
|
||||
$this->shipping[ $key ] = $shipping_line;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of coupon objects from the cart. Normalises data
|
||||
* into the same format for use by this class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_coupons() {
|
||||
//$this->coupons = $this->object->get_coupons(); @todo
|
||||
}
|
||||
|
||||
/**
|
||||
* Main cart totals. Set all order totals here after calculation.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function calculate_totals() {
|
||||
parent::calculate_totals();
|
||||
|
||||
$this->object->set_shipping_total( $this->get_total( 'shipping_total' ) );
|
||||
$this->object->set_shipping_tax( $this->get_total( 'shipping_tax_total' ) );
|
||||
$this->object->set_cart_tax( $this->get_total( 'tax_total' ) );
|
||||
$this->object->set_total( $this->get_total( 'total' ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
/**
|
||||
* Tests for the totals class.
|
||||
*
|
||||
* @package WooCommerce\Tests\Discounts
|
||||
*/
|
||||
|
||||
/**
|
||||
* WC_Tests_Order_Totals
|
||||
*/
|
||||
class WC_Tests_Order_Totals extends WC_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* Totals class for getter tests.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $totals;
|
||||
|
||||
/**
|
||||
* ID tracking for cleanup.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $ids = array();
|
||||
|
||||
/**
|
||||
* Order being tested.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $order;
|
||||
|
||||
/**
|
||||
* Setup the cart for totals calculation.
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->ids = array();
|
||||
|
||||
$tax_rate = array(
|
||||
'tax_rate_country' => '',
|
||||
'tax_rate_state' => '',
|
||||
'tax_rate' => '20.0000',
|
||||
'tax_rate_name' => 'VAT',
|
||||
'tax_rate_priority' => '1',
|
||||
'tax_rate_compound' => '0',
|
||||
'tax_rate_shipping' => '1',
|
||||
'tax_rate_order' => '1',
|
||||
'tax_rate_class' => '',
|
||||
);
|
||||
$tax_rate_id = WC_Tax::_insert_tax_rate( $tax_rate );
|
||||
update_option( 'woocommerce_calc_taxes', 'yes' );
|
||||
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
$product2 = WC_Helper_Product::create_simple_product();
|
||||
|
||||
WC_Helper_Shipping::create_simple_flat_rate();
|
||||
|
||||
$coupon = new WC_Coupon;
|
||||
$coupon->set_code( 'test-coupon-10' );
|
||||
$coupon->set_amount( 10 );
|
||||
$coupon->set_discount_type( 'percent' );
|
||||
$coupon->save();
|
||||
|
||||
$this->ids['tax_rate_ids'][] = $tax_rate_id;
|
||||
$this->ids['products'][] = $product;
|
||||
$this->ids['products'][] = $product2;
|
||||
$this->ids['coupons'][] = $coupon;
|
||||
|
||||
$this->order = new WC_Order();
|
||||
$this->order->add_product( $product, 1 );
|
||||
$this->order->add_product( $product2, 2 );
|
||||
|
||||
// @todo add coupon
|
||||
// @todo add fee
|
||||
|
||||
$this->order->save();
|
||||
|
||||
$this->totals = new WC_Order_Totals( $this->order );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after test.
|
||||
*/
|
||||
public function tearDown() {
|
||||
$this->order->delete();
|
||||
WC_Helper_Shipping::delete_simple_flat_rate();
|
||||
update_option( 'woocommerce_calc_taxes', 'no' );
|
||||
remove_action( 'woocommerce_cart_calculate_fees', array( $this, 'add_cart_fees_callback' ) );
|
||||
|
||||
foreach ( $this->ids['products'] as $product ) {
|
||||
$product->delete( true );
|
||||
}
|
||||
|
||||
foreach ( $this->ids['coupons'] as $coupon ) {
|
||||
$coupon->delete( true );
|
||||
wp_cache_delete( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $coupon->get_code(), 'coupons' );
|
||||
}
|
||||
|
||||
foreach ( $this->ids['tax_rate_ids'] as $tax_rate_id ) {
|
||||
WC_Tax::_delete_tax_rate( $tax_rate_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that cart totals get updated.
|
||||
*/
|
||||
public function test_order_totals() {
|
||||
$this->assertEquals( 90.40, $this->order->get_total() );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue