Merge pull request #16517 from woocommerce/integrate-cart-sessions-class
Integrate cart sessions, getters and setters
This commit is contained in:
commit
b0f190fa1d
|
@ -26,7 +26,7 @@ final class WC_Cart_Totals {
|
|||
* @since 3.2.0
|
||||
* @var array
|
||||
*/
|
||||
protected $object;
|
||||
protected $cart;
|
||||
|
||||
/**
|
||||
* Reference to customer object.
|
||||
|
@ -69,12 +69,20 @@ final class WC_Cart_Totals {
|
|||
protected $coupons = array();
|
||||
|
||||
/**
|
||||
* Discount amounts in cents after calculation for the cart.
|
||||
* Item/coupon discount totals.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @var array
|
||||
*/
|
||||
protected $discount_totals = array();
|
||||
protected $coupon_discount_totals = array();
|
||||
|
||||
/**
|
||||
* Item/coupon discount tax totals.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @var array
|
||||
*/
|
||||
protected $coupon_discount_tax_totals = array();
|
||||
|
||||
/**
|
||||
* Should taxes be calculated?
|
||||
|
@ -97,12 +105,9 @@ final class WC_Cart_Totals {
|
|||
'items_total' => 0,
|
||||
'items_total_tax' => 0,
|
||||
'total' => 0,
|
||||
'taxes' => array(),
|
||||
'tax_total' => 0,
|
||||
'shipping_total' => 0,
|
||||
'shipping_tax_total' => 0,
|
||||
'discounts_total' => 0,
|
||||
'discounts_tax_total' => 0,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -113,7 +118,7 @@ final class WC_Cart_Totals {
|
|||
*/
|
||||
public function __construct( &$cart = null ) {
|
||||
if ( is_a( $cart, 'WC_Cart' ) ) {
|
||||
$this->object = $cart;
|
||||
$this->cart = $cart;
|
||||
$this->calculate_tax = wc_tax_enabled() && ! $cart->get_customer()->get_is_vat_exempt();
|
||||
$this->calculate();
|
||||
}
|
||||
|
@ -126,8 +131,8 @@ final class WC_Cart_Totals {
|
|||
*/
|
||||
protected function calculate() {
|
||||
$this->calculate_item_totals();
|
||||
$this->calculate_fee_totals();
|
||||
$this->calculate_shipping_totals();
|
||||
$this->calculate_fee_totals();
|
||||
$this->calculate_totals();
|
||||
}
|
||||
|
||||
|
@ -140,6 +145,8 @@ final class WC_Cart_Totals {
|
|||
protected function get_default_item_props() {
|
||||
return (object) array(
|
||||
'object' => null,
|
||||
'tax_class' => '',
|
||||
'taxable' => false,
|
||||
'quantity' => 0,
|
||||
'product' => false,
|
||||
'price_includes_tax' => false,
|
||||
|
@ -159,6 +166,9 @@ final class WC_Cart_Totals {
|
|||
*/
|
||||
protected function get_default_fee_props() {
|
||||
return (object) array(
|
||||
'object' => null,
|
||||
'tax_class' => '',
|
||||
'taxable' => false,
|
||||
'total_tax' => 0,
|
||||
'taxes' => array(),
|
||||
);
|
||||
|
@ -172,6 +182,9 @@ final class WC_Cart_Totals {
|
|||
*/
|
||||
protected function get_default_shipping_props() {
|
||||
return (object) array(
|
||||
'object' => null,
|
||||
'tax_class' => '',
|
||||
'taxable' => false,
|
||||
'total' => 0,
|
||||
'total_tax' => 0,
|
||||
'taxes' => array(),
|
||||
|
@ -200,12 +213,14 @@ final class WC_Cart_Totals {
|
|||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_items() {
|
||||
protected function get_items_from_cart() {
|
||||
$this->items = array();
|
||||
|
||||
foreach ( $this->object->get_cart() as $cart_item_key => $cart_item ) {
|
||||
foreach ( $this->cart->get_cart() as $cart_item_key => $cart_item ) {
|
||||
$item = $this->get_default_item_props();
|
||||
$item->object = $cart_item;
|
||||
$item->tax_class = $cart_item['data']->get_tax_class();
|
||||
$item->taxable = 'taxable' === $cart_item['data']->get_tax_status();
|
||||
$item->price_includes_tax = wc_prices_include_tax();
|
||||
$item->quantity = $cart_item['quantity'];
|
||||
$item->subtotal = wc_add_number_precision_deep( $cart_item['data']->get_price() ) * $cart_item['quantity'];
|
||||
|
@ -221,17 +236,19 @@ final class WC_Cart_Totals {
|
|||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_fees() {
|
||||
protected function get_fees_from_cart() {
|
||||
$this->fees = array();
|
||||
$this->object->calculate_fees();
|
||||
$this->cart->calculate_fees();
|
||||
|
||||
foreach ( $this->object->get_fees() as $fee_key => $fee_object ) {
|
||||
$fee = $this->get_default_fee_props();
|
||||
$fee->object = $fee_object;
|
||||
$fee->total = wc_add_number_precision_deep( $fee->object->amount );
|
||||
foreach ( $this->cart->get_fees() as $fee_key => $fee_object ) {
|
||||
$fee = $this->get_default_fee_props();
|
||||
$fee->object = $fee_object;
|
||||
$fee->tax_class = $fee->object->tax_class;
|
||||
$fee->taxable = $fee->object->taxable;
|
||||
$fee->total = wc_add_number_precision_deep( $fee->object->amount );
|
||||
|
||||
if ( $this->calculate_tax && $fee->object->taxable ) {
|
||||
$fee->taxes = WC_Tax::calc_tax( $fee->total, WC_Tax::get_rates( $fee->object->tax_class, $this->object->get_customer() ), false );
|
||||
$fee->taxes = WC_Tax::calc_tax( $fee->total, WC_Tax::get_rates( $fee->object->tax_class, $this->cart->get_customer() ), false );
|
||||
$fee->total_tax = array_sum( $fee->taxes );
|
||||
|
||||
if ( ! $this->round_at_subtotal() ) {
|
||||
|
@ -248,12 +265,14 @@ final class WC_Cart_Totals {
|
|||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_shipping() {
|
||||
protected function get_shipping_from_cart() {
|
||||
$this->shipping = array();
|
||||
|
||||
foreach ( $this->object->calculate_shipping() as $key => $shipping_object ) {
|
||||
foreach ( $this->cart->calculate_shipping() as $key => $shipping_object ) {
|
||||
$shipping_line = $this->get_default_shipping_props();
|
||||
$shipping_line->object = $shipping_object;
|
||||
$shipping_line->tax_class = get_option( 'woocommerce_shipping_tax_class' );
|
||||
$shipping_line->taxable = true;
|
||||
$shipping_line->total = wc_add_number_precision_deep( $shipping_object->cost );
|
||||
$shipping_line->taxes = wc_add_number_precision_deep( $shipping_object->taxes );
|
||||
$shipping_line->total_tax = wc_add_number_precision_deep( array_sum( $shipping_object->taxes ) );
|
||||
|
@ -272,8 +291,8 @@ final class WC_Cart_Totals {
|
|||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function set_coupons() {
|
||||
$this->coupons = $this->object->get_coupons();
|
||||
protected function get_coupons_from_cart() {
|
||||
$this->coupons = $this->cart->get_coupons();
|
||||
|
||||
foreach ( $this->coupons as $coupon ) {
|
||||
switch ( $coupon->get_discount_type() ) {
|
||||
|
@ -292,7 +311,7 @@ final class WC_Cart_Totals {
|
|||
}
|
||||
}
|
||||
|
||||
uasort( $this->coupons, array( $this, 'sort_coupons' ) );
|
||||
uasort( $this->coupons, array( $this, 'sort_coupons_callback' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -302,7 +321,7 @@ final class WC_Cart_Totals {
|
|||
* @param WC_Coupon $b Coupon object.
|
||||
* @return int
|
||||
*/
|
||||
protected function sort_coupons( $a, $b ) {
|
||||
protected function sort_coupons_callback( $a, $b ) {
|
||||
if ( $a->sort === $b->sort ) {
|
||||
return $a->get_id() - $b->get_id();
|
||||
}
|
||||
|
@ -344,7 +363,7 @@ final class WC_Cart_Totals {
|
|||
*/
|
||||
protected function get_discounted_price_in_cents( $item_key ) {
|
||||
$item = $this->items[ $item_key ];
|
||||
$price = isset( $this->discount_totals[ $item_key ] ) ? $item->subtotal - $this->discount_totals[ $item_key ] : $item->subtotal;
|
||||
$price = isset( $this->coupon_discount_totals[ $item_key ] ) ? $item->subtotal - $this->coupon_discount_totals[ $item_key ] : $item->subtotal;
|
||||
|
||||
if ( $item->price_includes_tax ) {
|
||||
$price += $item->subtotal_tax;
|
||||
|
@ -360,7 +379,33 @@ final class WC_Cart_Totals {
|
|||
*/
|
||||
protected function get_item_tax_rates( $item ) {
|
||||
$tax_class = $item->product->get_tax_class();
|
||||
return isset( $this->item_tax_rates[ $tax_class ] ) ? $this->item_tax_rates[ $tax_class ] : $this->item_tax_rates[ $tax_class ] = WC_Tax::get_rates( $item->product->get_tax_class(), $this->object->get_customer() );
|
||||
return isset( $this->item_tax_rates[ $tax_class ] ) ? $this->item_tax_rates[ $tax_class ] : $this->item_tax_rates[ $tax_class ] = WC_Tax::get_rates( $item->product->get_tax_class(), $this->cart->get_customer() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item costs grouped by tax class.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @return array
|
||||
*/
|
||||
protected function get_item_costs_by_tax_class() {
|
||||
$tax_classes = array(
|
||||
'non-taxable' => 0,
|
||||
);
|
||||
|
||||
foreach ( $this->items + $this->fees + $this->shipping as $item ) {
|
||||
if ( ! isset( $tax_classes[ $item->tax_class ] ) ) {
|
||||
$tax_classes[ $item->tax_class ] = 0;
|
||||
}
|
||||
|
||||
if ( $item->taxable ) {
|
||||
$tax_classes[ $item->tax_class ] += $item->total;
|
||||
} else {
|
||||
$tax_classes['non-taxable'] += $item->total;
|
||||
}
|
||||
}
|
||||
|
||||
return $tax_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -399,32 +444,56 @@ final class WC_Cart_Totals {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all tax rows from items (including shipping and product line items).
|
||||
* Get taxes merged by type.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @since 3.2.0
|
||||
* @param array|string $types Types to merge and return. Defaults to all.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_merged_taxes() {
|
||||
protected function get_merged_taxes( $in_cents = false, $types = array( 'items', 'fees', 'shipping' ) ) {
|
||||
$items = array();
|
||||
$taxes = array();
|
||||
|
||||
foreach ( array_merge( $this->items, $this->fees, $this->shipping ) as $item ) {
|
||||
foreach ( $item->taxes as $rate_id => $rate ) {
|
||||
$taxes[ $rate_id ] = array( 'tax_total' => 0, 'shipping_tax_total' => 0 );
|
||||
if ( is_string( $types ) ) {
|
||||
$types = array( $types );
|
||||
}
|
||||
|
||||
foreach ( $types as $type ) {
|
||||
if ( isset( $this->$type ) ) {
|
||||
$items = array_merge( $items, $this->$type );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->items + $this->fees as $item ) {
|
||||
foreach ( $items as $item ) {
|
||||
foreach ( $item->taxes as $rate_id => $rate ) {
|
||||
$taxes[ $rate_id ]['tax_total'] = $taxes[ $rate_id ]['tax_total'] + $rate;
|
||||
if ( ! isset( $taxes[ $rate_id ] ) ) {
|
||||
$taxes[ $rate_id ] = 0;
|
||||
}
|
||||
$taxes[ $rate_id ] += $rate;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->shipping as $item ) {
|
||||
foreach ( $item->taxes as $rate_id => $rate ) {
|
||||
$taxes[ $rate_id ]['shipping_tax_total'] = $taxes[ $rate_id ]['shipping_tax_total'] + $rate;
|
||||
return $in_cents ? $taxes : wc_remove_number_precision_deep( $taxes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine item taxes into a single array, preserving keys.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @param array $taxes Taxes to combine.
|
||||
* @return array
|
||||
*/
|
||||
protected function combine_item_taxes( $item_taxes ) {
|
||||
$merged_taxes = array();
|
||||
foreach ( $item_taxes as $taxes ) {
|
||||
foreach ( $taxes as $tax_id => $tax_amount ) {
|
||||
if ( ! isset( $merged_taxes[ $tax_id ] ) ) {
|
||||
$merged_taxes[ $tax_id ] = 0;
|
||||
}
|
||||
$merged_taxes[ $tax_id ] += $tax_amount;
|
||||
}
|
||||
}
|
||||
return $taxes;
|
||||
return $merged_taxes;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -439,9 +508,9 @@ final class WC_Cart_Totals {
|
|||
* @since 3.2.0
|
||||
*/
|
||||
protected function calculate_item_totals() {
|
||||
$this->set_items();
|
||||
$this->get_items_from_cart();
|
||||
$this->calculate_item_subtotals();
|
||||
$this->calculate_item_discounts();
|
||||
$this->calculate_discounts();
|
||||
|
||||
foreach ( $this->items as $item_key => $item ) {
|
||||
$item->total = $this->get_discounted_price_in_cents( $item_key );
|
||||
|
@ -453,10 +522,10 @@ final class WC_Cart_Totals {
|
|||
*
|
||||
* This is legacy and should probably be deprecated in the future.
|
||||
* $item->object is the cart item object.
|
||||
* $this->object is the cart object.
|
||||
* $this->cart is the cart object.
|
||||
*/
|
||||
$item->total = wc_add_number_precision(
|
||||
apply_filters( 'woocommerce_get_discounted_price', wc_remove_number_precision( $item->total ), $item->object, $this->object )
|
||||
apply_filters( 'woocommerce_get_discounted_price', wc_remove_number_precision( $item->total ), $item->object, $this->cart )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -475,8 +544,9 @@ final class WC_Cart_Totals {
|
|||
}
|
||||
}
|
||||
|
||||
$this->object->cart_contents[ $item_key ]['line_total'] = wc_remove_number_precision( $item->total );
|
||||
$this->object->cart_contents[ $item_key ]['line_tax'] = wc_remove_number_precision( $item->total_tax );
|
||||
$this->cart->cart_contents[ $item_key ]['line_tax_data']['total'] = wc_remove_number_precision_deep( $item->taxes );
|
||||
$this->cart->cart_contents[ $item_key ]['line_total'] = wc_remove_number_precision( $item->total );
|
||||
$this->cart->cart_contents[ $item_key ]['line_tax'] = wc_remove_number_precision( $item->total_tax );
|
||||
}
|
||||
|
||||
$this->set_total( 'items_total', array_sum( array_values( wp_list_pluck( $this->items, 'total' ) ) ) );
|
||||
|
@ -503,6 +573,8 @@ final class WC_Cart_Totals {
|
|||
$item = $this->adjust_non_base_location_price( $item );
|
||||
}
|
||||
|
||||
$subtotal_taxes = array();
|
||||
|
||||
if ( $this->calculate_tax && $item->product->is_taxable() ) {
|
||||
$subtotal_taxes = WC_Tax::calc_tax( $item->subtotal, $item->tax_rates, $item->price_includes_tax );
|
||||
$item->subtotal_tax = array_sum( $subtotal_taxes );
|
||||
|
@ -516,26 +588,27 @@ final class WC_Cart_Totals {
|
|||
}
|
||||
}
|
||||
|
||||
$this->object->cart_contents[ $item_key ]['line_subtotal'] = wc_remove_number_precision( $item->subtotal );
|
||||
$this->object->cart_contents[ $item_key ]['line_subtotal_tax'] = wc_remove_number_precision( $item->subtotal_tax );
|
||||
$this->cart->cart_contents[ $item_key ]['line_tax_data'] = array( 'subtotal' => wc_remove_number_precision_deep( $subtotal_taxes ) );
|
||||
$this->cart->cart_contents[ $item_key ]['line_subtotal'] = wc_remove_number_precision( $item->subtotal );
|
||||
$this->cart->cart_contents[ $item_key ]['line_subtotal_tax'] = wc_remove_number_precision( $item->subtotal_tax );
|
||||
}
|
||||
$this->set_total( 'items_subtotal', array_sum( array_values( wp_list_pluck( $this->items, 'subtotal' ) ) ) );
|
||||
$this->set_total( 'items_subtotal_tax', array_sum( array_values( wp_list_pluck( $this->items, 'subtotal_tax' ) ) ) );
|
||||
|
||||
$this->object->subtotal = $this->get_total( 'items_subtotal' ) + $this->get_total( 'items_subtotal_tax' );
|
||||
$this->object->subtotal_ex_tax = $this->get_total( 'items_subtotal' );
|
||||
$this->cart->set_subtotal( $this->get_total( 'items_subtotal' ) );
|
||||
$this->cart->set_subtotal_tax( $this->get_total( 'items_subtotal_tax' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate coupon based discounts which change item prices.
|
||||
* Calculate COUPON based discounts which change item prices.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @uses WC_Discounts class.
|
||||
*/
|
||||
protected function calculate_item_discounts() {
|
||||
$this->set_coupons();
|
||||
protected function calculate_discounts() {
|
||||
$this->get_coupons_from_cart();
|
||||
|
||||
$discounts = new WC_Discounts( $this->object );
|
||||
$discounts = new WC_Discounts( $this->cart );
|
||||
|
||||
foreach ( $this->coupons as $coupon ) {
|
||||
$discounts->apply_coupon( $coupon );
|
||||
|
@ -549,11 +622,11 @@ final class WC_Cart_Totals {
|
|||
foreach ( $discounts->get_discounts( true ) as $coupon_code => $coupon_discounts ) {
|
||||
$coupon_discount_tax_amounts[ $coupon_code ] = 0;
|
||||
|
||||
foreach ( $coupon_discounts as $item_key => $item_discount ) {
|
||||
foreach ( $coupon_discounts as $item_key => $coupon_discount ) {
|
||||
$item = $this->items[ $item_key ];
|
||||
|
||||
if ( $item->product->is_taxable() ) {
|
||||
$item_tax = array_sum( WC_Tax::calc_tax( $item_discount, $item->tax_rates, $item->price_includes_tax ) );
|
||||
$item_tax = array_sum( WC_Tax::calc_tax( $coupon_discount, $item->tax_rates, $item->price_includes_tax ) );
|
||||
$coupon_discount_tax_amounts[ $coupon_code ] += $item_tax;
|
||||
}
|
||||
}
|
||||
|
@ -564,27 +637,11 @@ final class WC_Cart_Totals {
|
|||
}
|
||||
}
|
||||
|
||||
$this->discount_totals = $discounts->get_discounts_by_item( true );
|
||||
$this->object->coupon_discount_amounts = wc_remove_number_precision_deep( $coupon_discount_amounts );
|
||||
$this->object->coupon_discount_tax_amounts = wc_remove_number_precision_deep( $coupon_discount_tax_amounts );
|
||||
$this->coupon_discount_totals = (array) $discounts->get_discounts_by_item( true );
|
||||
$this->coupon_discount_tax_totals = $coupon_discount_tax_amounts;
|
||||
|
||||
$this->set_total( 'discounts_total', ! empty( $this->discount_totals ) ? array_sum( $this->discount_totals ) : 0 );
|
||||
$this->set_total( 'discounts_tax_total', array_sum( $coupon_discount_tax_amounts ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return discounted tax amount for an item.
|
||||
*
|
||||
* @param object $item Item object.
|
||||
* @param int $discount_amount Amount of discount.
|
||||
* @return int
|
||||
*/
|
||||
protected function get_item_discount_tax( $item, $discount_amount ) {
|
||||
if ( $item->product->is_taxable() ) {
|
||||
$taxes = WC_Tax::calc_tax( $discount_amount, $item->tax_rates, false );
|
||||
return array_sum( $taxes );
|
||||
}
|
||||
return 0;
|
||||
$this->cart->set_coupon_discount_totals( wc_remove_number_precision_deep( $coupon_discount_amounts ) );
|
||||
$this->cart->set_coupon_discount_tax_totals( wc_remove_number_precision_deep( $coupon_discount_tax_amounts ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -595,15 +652,18 @@ final class WC_Cart_Totals {
|
|||
* @since 3.2.0
|
||||
*/
|
||||
protected function calculate_fee_totals() {
|
||||
$this->set_fees();
|
||||
$this->get_fees_from_cart();
|
||||
$this->set_total( 'fees_total', array_sum( wp_list_pluck( $this->fees, 'total' ) ) );
|
||||
$this->set_total( 'fees_total_tax', array_sum( wp_list_pluck( $this->fees, 'total_tax' ) ) );
|
||||
|
||||
foreach ( $this->fees as $fee_key => $fee ) {
|
||||
$this->object->fees[ $fee_key ]->tax = wc_remove_number_precision_deep( $fee->total_tax );
|
||||
$this->object->fees[ $fee_key ]->tax_data = wc_remove_number_precision_deep( $fee->taxes );
|
||||
$this->cart->fees[ $fee_key ]->tax = wc_remove_number_precision_deep( $fee->total_tax );
|
||||
$this->cart->fees[ $fee_key ]->tax_data = wc_remove_number_precision_deep( $fee->taxes );
|
||||
}
|
||||
$this->object->fee_total = wc_remove_number_precision_deep( array_sum( wp_list_pluck( $this->fees, 'total' ) ) );
|
||||
|
||||
$this->cart->set_fee_total( wc_remove_number_precision_deep( array_sum( wp_list_pluck( $this->fees, 'total' ) ) ) );
|
||||
$this->cart->set_fee_tax( wc_remove_number_precision_deep( array_sum( wp_list_pluck( $this->fees, 'total_tax' ) ) ) );
|
||||
$this->cart->set_fee_taxes( wc_remove_number_precision_deep( $this->combine_item_taxes( wp_list_pluck( $this->fees, 'taxes' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -612,12 +672,13 @@ final class WC_Cart_Totals {
|
|||
* @since 3.2.0
|
||||
*/
|
||||
protected function calculate_shipping_totals() {
|
||||
$this->set_shipping();
|
||||
$this->get_shipping_from_cart();
|
||||
$this->set_total( 'shipping_total', array_sum( wp_list_pluck( $this->shipping, 'total' ) ) );
|
||||
$this->set_total( 'shipping_tax_total', array_sum( wp_list_pluck( $this->shipping, 'total_tax' ) ) );
|
||||
|
||||
$this->object->shipping_total = $this->get_total( 'shipping_total' );
|
||||
$this->object->shipping_tax_total = $this->get_total( 'shipping_tax_total' );
|
||||
$this->cart->set_shipping_total( $this->get_total( 'shipping_total' ) );
|
||||
$this->cart->set_shipping_tax( $this->get_total( 'shipping_tax_total' ) );
|
||||
$this->cart->set_shipping_taxes( wc_remove_number_precision_deep( $this->combine_item_taxes( wp_list_pluck( $this->shipping, 'taxes' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -626,26 +687,24 @@ final class WC_Cart_Totals {
|
|||
* @since 3.2.0
|
||||
*/
|
||||
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( '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 ) ) );
|
||||
$this->set_total( 'discounts_total', array_sum( $this->coupon_discount_totals ) );
|
||||
$this->set_total( 'discounts_tax_total', array_sum( $this->coupon_discount_tax_totals ) );
|
||||
$this->set_total( 'total', round( $this->get_total( 'items_total', true ) + $this->get_total( 'fees_total', true ) + $this->get_total( 'shipping_total', true ) + array_sum( $this->get_merged_taxes( true ) ) ) );
|
||||
|
||||
// Add totals to cart object.
|
||||
$this->object->taxes = wp_list_pluck( $this->get_total( 'taxes' ), 'shipping_tax_total' );
|
||||
$this->object->shipping_taxes = wp_list_pluck( $this->get_total( 'taxes' ), 'tax_total' );
|
||||
$this->object->cart_contents_total = $this->get_total( 'items_total' );
|
||||
$this->object->tax_total = $this->get_total( 'tax_total' );
|
||||
$this->object->total = $this->get_total( 'total' );
|
||||
$this->object->discount_cart = $this->get_total( 'discounts_total' ) - $this->get_total( 'discounts_tax_total' );
|
||||
$this->object->discount_cart_tax = $this->get_total( 'discounts_tax_total' );
|
||||
$this->cart->set_cart_contents_total( $this->get_total( 'items_total' ) );
|
||||
$this->cart->set_cart_contents_tax( array_sum( $this->get_merged_taxes( false, 'items' ) ) );
|
||||
$this->cart->set_cart_contents_taxes( $this->get_merged_taxes( false, 'items' ) );
|
||||
$this->cart->set_discount_total( $this->get_total( 'discounts_total' ) );
|
||||
$this->cart->set_discount_tax( $this->get_total( 'discounts_tax_total' ) );
|
||||
$this->cart->set_total_tax( array_sum( $this->get_merged_taxes( false ) ) );
|
||||
|
||||
// Allow plugins to hook and alter totals before final total is calculated.
|
||||
if ( has_action( 'woocommerce_calculate_totals' ) ) {
|
||||
do_action( 'woocommerce_calculate_totals', $this->object );
|
||||
do_action( 'woocommerce_calculate_totals', $this->cart );
|
||||
}
|
||||
|
||||
// Allow plugins to filter the grand total, and sum the cart totals in case of modifications.
|
||||
$totals_to_sum = wc_add_number_precision_deep( array( $this->object->cart_contents_total, $this->object->tax_total, $this->object->shipping_tax_total, $this->object->shipping_total, $this->object->fee_total ) );
|
||||
$this->object->total = max( 0, apply_filters( 'woocommerce_calculated_total', wc_remove_number_precision( round( array_sum( $totals_to_sum ) ) ), $this->object ) );
|
||||
$this->cart->set_total( max( 0, apply_filters( 'woocommerce_calculated_total', $this->get_total( 'total' ), $this->cart ) ) );
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -313,12 +313,12 @@ class WC_Checkout {
|
|||
$order->set_customer_user_agent( wc_get_user_agent() );
|
||||
$order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
|
||||
$order->set_payment_method( isset( $available_gateways[ $data['payment_method'] ] ) ? $available_gateways[ $data['payment_method'] ] : $data['payment_method'] );
|
||||
$order->set_shipping_total( WC()->cart->shipping_total );
|
||||
$order->set_discount_total( WC()->cart->get_cart_discount_total() );
|
||||
$order->set_discount_tax( WC()->cart->get_cart_discount_tax_total() );
|
||||
$order->set_cart_tax( WC()->cart->tax_total );
|
||||
$order->set_shipping_tax( WC()->cart->shipping_tax_total );
|
||||
$order->set_total( WC()->cart->total );
|
||||
$order->set_shipping_total( WC()->cart->get_shipping_total() );
|
||||
$order->set_discount_total( WC()->cart->get_discount_total() );
|
||||
$order->set_discount_tax( WC()->cart->get_discount_tax() );
|
||||
$order->set_cart_tax( WC()->cart->get_cart_contents_tax() + WC()->cart->get_fee_tax() );
|
||||
$order->set_shipping_tax( WC()->cart->get_shipping_tax() );
|
||||
$order->set_total( WC()->cart->get_total( 'edit' ) );
|
||||
$this->create_order_line_items( $order, WC()->cart );
|
||||
$this->create_order_fee_lines( $order, WC()->cart );
|
||||
$this->create_order_shipping_lines( $order, WC()->session->get( 'chosen_shipping_methods' ), WC()->shipping->get_packages() );
|
||||
|
|
|
@ -72,6 +72,22 @@ class WC_Shipping {
|
|||
wc_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'woocommerce' ), '2.1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter.
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
// Grab from cart for backwards compatibility with versions prior to 3.2.
|
||||
if ( 'shipping_total' === $name ){
|
||||
return wc()->cart->get_shipping_total();
|
||||
}
|
||||
if ( 'shipping_taxes' === $name ){
|
||||
return wc()->cart->get_shipping_taxes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize shipping.
|
||||
*/
|
||||
|
|
|
@ -20,6 +20,29 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
*/
|
||||
abstract class WC_Legacy_Cart {
|
||||
|
||||
/**
|
||||
* Array of defaults. Not used since 3.2.
|
||||
*
|
||||
* @deprecated 3.2.0
|
||||
*/
|
||||
public $cart_session_data = array(
|
||||
'cart_contents_total' => 0,
|
||||
'total' => 0,
|
||||
'subtotal' => 0,
|
||||
'subtotal_ex_tax' => 0,
|
||||
'tax_total' => 0,
|
||||
'taxes' => array(),
|
||||
'shipping_taxes' => array(),
|
||||
'discount_cart' => 0,
|
||||
'discount_cart_tax' => 0,
|
||||
'shipping_total' => 0,
|
||||
'shipping_tax_total' => 0,
|
||||
'coupon_discount_amounts' => array(),
|
||||
'coupon_discount_tax_amounts' => array(),
|
||||
'fee_total' => 0,
|
||||
'fees' => array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Contains an array of coupon usage counts after they have been applied.
|
||||
*
|
||||
|
@ -28,6 +51,179 @@ abstract class WC_Legacy_Cart {
|
|||
*/
|
||||
public $coupon_applied_count = array();
|
||||
|
||||
/**
|
||||
* Magic getters.
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
switch ( $name ) {
|
||||
case 'dp' :
|
||||
return wc_get_price_decimals();
|
||||
case 'prices_include_tax' :
|
||||
return wc_prices_include_tax();
|
||||
case 'round_at_subtotal' :
|
||||
return 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' );
|
||||
// map old public props to methods.
|
||||
case 'cart_contents_total' :
|
||||
return $this->get_cart_contents_total();
|
||||
case 'total' :
|
||||
return $this->get_total( 'edit' );
|
||||
case 'subtotal' :
|
||||
return $this->get_subtotal() + $this->get_subtotal_tax();
|
||||
case 'subtotal_ex_tax' :
|
||||
return $this->get_subtotal();
|
||||
case 'tax_total' :
|
||||
return $this->get_fee_tax() + $this->get_cart_contents_tax();
|
||||
case 'taxes' :
|
||||
return $this->get_taxes();
|
||||
case 'shipping_taxes' :
|
||||
return $this->get_shipping_taxes();
|
||||
case 'fee_total' :
|
||||
return $this->get_fee_total();
|
||||
case 'discount_cart' :
|
||||
return $this->get_discount_total();
|
||||
case 'discount_cart_tax' :
|
||||
return $this->get_discount_tax();
|
||||
case 'shipping_total' :
|
||||
return $this->get_shipping_total();
|
||||
case 'shipping_tax_total' :
|
||||
return $this->get_shipping_tax();
|
||||
case 'coupon_discount_amounts' :
|
||||
return $this->get_coupon_discount_totals();
|
||||
case 'coupon_discount_tax_amounts' :
|
||||
return $this->get_coupon_discount_tax_totals();
|
||||
case 'display_totals_ex_tax' :
|
||||
case 'display_cart_ex_tax' :
|
||||
return 'excl' === $this->tax_display_cart;
|
||||
case 'cart_contents_weight' :
|
||||
return $this->get_cart_contents_weight();
|
||||
case 'cart_contents_count' :
|
||||
return $this->get_cart_contents_count();
|
||||
case 'tax' :
|
||||
wc_deprecated_argument( 'WC_Cart->tax', '2.3', 'Use WC_Tax:: directly' );
|
||||
$this->tax = new WC_Tax();
|
||||
return $this->tax;
|
||||
case 'discount_total':
|
||||
wc_deprecated_argument( 'WC_Cart->discount_total', '2.3', 'After tax coupons are no longer supported. For more information see: https://woocommerce.wordpress.com/2014/12/upcoming-coupon-changes-in-woocommerce-2-3/' );
|
||||
return 0;
|
||||
case 'coupons' :
|
||||
return $this->get_coupons();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Map legacy variables to setters.
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @param mixed $value Value to set.
|
||||
*/
|
||||
public function __set( $name, $value ) {
|
||||
switch ( $name ) {
|
||||
case 'cart_contents_total' :
|
||||
$this->set_cart_contents_total( $value );
|
||||
break;
|
||||
case 'total' :
|
||||
$this->set_total( $value );
|
||||
break;
|
||||
case 'subtotal' :
|
||||
$this->set_subtotal( $value );
|
||||
break;
|
||||
case 'subtotal_ex_tax' :
|
||||
$this->set_subtotal( $value );
|
||||
break;
|
||||
case 'tax_total' :
|
||||
$this->set_cart_contents_tax( $value );
|
||||
$this->set_fee_tax( 0 );
|
||||
break;
|
||||
case 'taxes' :
|
||||
$this->set_cart_contents_taxes( $value );
|
||||
break;
|
||||
case 'shipping_taxes' :
|
||||
$this->set_shipping_taxes( $value );
|
||||
break;
|
||||
case 'fee_total' :
|
||||
$this->set_fee_total( $value );
|
||||
break;
|
||||
case 'discount_cart' :
|
||||
$this->set_discount_total( $value );
|
||||
break;
|
||||
case 'discount_cart_tax' :
|
||||
$this->set_discount_tax( $value );
|
||||
break;
|
||||
case 'shipping_total' :
|
||||
$this->set_shipping_total( $value );
|
||||
break;
|
||||
case 'shipping_tax_total' :
|
||||
$this->set_shipping_tax( $value );
|
||||
break;
|
||||
case 'coupon_discount_amounts' :
|
||||
$this->set_coupon_discount_totals( $value );
|
||||
break;
|
||||
case 'coupon_discount_tax_amounts' :
|
||||
$this->set_coupon_discount_tax_totals( $value );
|
||||
break;
|
||||
default :
|
||||
$this->$name = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods moved to session class in 3.2.0.
|
||||
*/
|
||||
public function get_cart_from_session() { $this->session->get_cart_from_session(); }
|
||||
public function maybe_set_cart_cookies() { $this->session->maybe_set_cart_cookies(); }
|
||||
public function set_session() { $this->session->set_session(); }
|
||||
public function get_cart_for_session() { $this->session->get_cart_for_session(); }
|
||||
public function persistent_cart_update() { $this->session->persistent_cart_update(); }
|
||||
public function persistent_cart_destroy() { $this->session->persistent_cart_destroy(); }
|
||||
|
||||
/**
|
||||
* Get the total of all cart discounts.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function get_cart_discount_total() {
|
||||
return $this->get_discount_total();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total of all cart tax discounts (used for discounts on tax inclusive prices).
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function get_cart_discount_tax_total() {
|
||||
return $this->get_discount_tax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renamed for consistency.
|
||||
*
|
||||
* @param string $coupon_code
|
||||
* @return bool True if the coupon is applied, false if it does not exist or cannot be applied.
|
||||
*/
|
||||
public function add_discount( $coupon_code ) {
|
||||
return $this->apply_coupon( $coupon_code );
|
||||
}
|
||||
/**
|
||||
* Remove taxes.
|
||||
*
|
||||
* @deprecated 3.2.0 Taxes are never calculated if customer is tax except making this function unused.
|
||||
*/
|
||||
public function remove_taxes() {
|
||||
wc_deprecated_function( 'WC_Cart::remove_taxes', '3.2', '' );
|
||||
}
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @deprecated 3.2.0 Session is loaded via hooks rather than directly.
|
||||
*/
|
||||
public function init() {
|
||||
wc_deprecated_function( 'WC_Cart::init', '3.2', '' );
|
||||
$this->get_cart_from_session();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to apply discounts to a product and get the discounted price (before tax is applied).
|
||||
*
|
||||
|
|
|
@ -163,9 +163,9 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
|
|||
$total = WC()->cart->get_displayed_subtotal();
|
||||
|
||||
if ( 'incl' === WC()->cart->tax_display_cart ) {
|
||||
$total = round( $total - ( WC()->cart->get_cart_discount_total() + WC()->cart->get_cart_discount_tax_total() ), wc_get_price_decimals() );
|
||||
$total = round( $total - ( WC()->cart->get_discount_total() + WC()->cart->get_discount_tax() ), wc_get_price_decimals() );
|
||||
} else {
|
||||
$total = round( $total - WC()->cart->get_cart_discount_total(), wc_get_price_decimals() );
|
||||
$total = round( $total - WC()->cart->get_discount_total(), wc_get_price_decimals() );
|
||||
}
|
||||
|
||||
if ( $total >= $this->min_amount ) {
|
||||
|
|
|
@ -174,7 +174,7 @@ class WC_Shipping_Legacy_Free_Shipping extends WC_Shipping_Method {
|
|||
}
|
||||
|
||||
if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ) ) && isset( WC()->cart->cart_contents_total ) ) {
|
||||
if ( WC()->cart->prices_include_tax ) {
|
||||
if ( wc_prices_include_tax() ) {
|
||||
$total = WC()->cart->cart_contents_total + array_sum( WC()->cart->taxes );
|
||||
} else {
|
||||
$total = WC()->cart->cart_contents_total;
|
||||
|
|
|
@ -344,12 +344,12 @@ function wc_cart_totals_shipping_method_label( $method ) {
|
|||
if ( $method->cost > 0 ) {
|
||||
if ( WC()->cart->tax_display_cart == 'excl' ) {
|
||||
$label .= ': ' . wc_price( $method->cost );
|
||||
if ( $method->get_shipping_tax() > 0 && WC()->cart->prices_include_tax ) {
|
||||
if ( $method->get_shipping_tax() > 0 && wc_prices_include_tax() ) {
|
||||
$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
|
||||
}
|
||||
} else {
|
||||
$label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() );
|
||||
if ( $method->get_shipping_tax() > 0 && ! WC()->cart->prices_include_tax ) {
|
||||
if ( $method->get_shipping_tax() > 0 && ! wc_prices_include_tax() ) {
|
||||
$label .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,13 +124,6 @@ class WC_Tests_Totals extends WC_Unit_Test_Case {
|
|||
'items_total' => 27.00,
|
||||
'items_total_tax' => 5.40,
|
||||
'total' => 90.40,
|
||||
'taxes' => array(
|
||||
$this->ids['tax_rate_ids'][0] => array(
|
||||
'tax_total' => 11.40,
|
||||
'shipping_tax_total' => 2.00,
|
||||
),
|
||||
),
|
||||
'tax_total' => 11.40,
|
||||
'shipping_total' => 10,
|
||||
'shipping_tax_total' => 2,
|
||||
'discounts_total' => 3.00,
|
||||
|
@ -144,13 +137,26 @@ class WC_Tests_Totals extends WC_Unit_Test_Case {
|
|||
public function test_cart_totals() {
|
||||
$cart = WC()->cart;
|
||||
|
||||
$this->assertEquals( 40.00, $cart->fee_total );
|
||||
$this->assertEquals( 40.00, $cart->get_fee_total() );
|
||||
$this->assertEquals( 27.00, $cart->get_cart_contents_total() );
|
||||
$this->assertEquals( 90.40, $cart->get_total( 'edit' ) );
|
||||
$this->assertEquals( 30.00, $cart->get_subtotal() );
|
||||
$this->assertEquals( 6.00, $cart->get_subtotal_tax() );
|
||||
$this->assertEquals( 5.40, $cart->get_cart_contents_tax() );
|
||||
$this->assertEquals( 5.40, array_sum( $cart->get_cart_contents_taxes() ) );
|
||||
$this->assertEquals( 6.00, $cart->get_fee_tax() );
|
||||
$this->assertEquals( 6.00, array_sum( $cart->get_fee_taxes() ) );
|
||||
$this->assertEquals( 3, $cart->get_discount_total() );
|
||||
$this->assertEquals( 0.60, $cart->get_discount_tax() );
|
||||
$this->assertEquals( 10, $cart->get_shipping_total() );
|
||||
$this->assertEquals( 2, $cart->get_shipping_tax() );
|
||||
|
||||
$this->assertEquals( 27.00, $cart->cart_contents_total );
|
||||
$this->assertEquals( 90.40, $cart->total );
|
||||
$this->assertEquals( 36.00, $cart->subtotal );
|
||||
$this->assertEquals( 30.00, $cart->subtotal_ex_tax );
|
||||
$this->assertEquals( 11.40, $cart->tax_total );
|
||||
$this->assertEquals( 2.40, $cart->discount_cart );
|
||||
$this->assertEquals( 3, $cart->discount_cart );
|
||||
$this->assertEquals( 0.60, $cart->discount_cart_tax );
|
||||
$this->assertEquals( 40.00, $cart->fee_total );
|
||||
$this->assertEquals( 10, $cart->shipping_total );
|
||||
|
|
Loading…
Reference in New Issue