/** * Uses the a subscription's combined price total calculated by WooCommerce to determine the * total price that should be charged per period. * * @since 1.2 */ public static function calculate_subscription_totals($total) { global $woocommerce; if (!self::cart_contains_subscription()) { return $total; } elseif ('sign_up_fee' == self::$recalculation_type) { // We've requested totals be recalculated with sign up fee only, we need to remove anything shipping related from the sign-up fee totals $total = $total - $woocommerce->cart->shipping_tax_total - $woocommerce->cart->shipping_total; $woocommerce->cart->shipping_taxes = array(); $woocommerce->cart->shipping_tax_total = 0; self::$recalculation_type = 'none'; return $total; } $base_sign_up_fee = self::get_cart_subscription_sign_up_fee(); if ($base_sign_up_fee == 0 || self::$recalculation_type == 'base_recurring_fee') { // Nothing to fudge here, but we still need to keep a record of recurring totals foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) { $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_total'] = $values['line_total']; $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_tax'] = $values['line_tax']; $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal'] = $values['line_subtotal']; $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal_tax'] = $values['line_subtotal_tax']; } $woocommerce->cart->recurring_cart_contents_total = $woocommerce->cart->cart_contents_total; $woocommerce->cart->recurring_discount_cart = $woocommerce->cart->discount_cart; $woocommerce->cart->recurring_discount_total = $woocommerce->cart->discount_total; $woocommerce->cart->recurring_subtotal = $woocommerce->cart->subtotal; $woocommerce->cart->recurring_subtotal_ex_tax = $woocommerce->cart->subtotal_ex_tax; $woocommerce->cart->recurring_taxes = $woocommerce->cart->get_taxes(); $woocommerce->cart->recurring_tax_total = $woocommerce->cart->tax_total; $woocommerce->cart->recurring_total = $total; // after calculating the recurring fee with discount, reset flag if (self::$recalculation_type == 'base_recurring_fee') { self::$recalculation_type = 'none'; return $total; } } else { // The $total = price per period + sign up fee, so lets derive each one individually $sign_up_fee_proportion = $base_sign_up_fee / ($base_sign_up_fee + self::$base_product_price); // self::$base_product_price as set in set_subscription_prices_for_calculation() $recurring_proportion = 1 - $sign_up_fee_proportion; foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) { $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_total'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_total'], $recurring_proportion); $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_tax'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_tax'], $recurring_proportion); $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_subtotal'], $recurring_proportion); $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal_tax'] = WC_Subscriptions_Manager::get_amount_from_proportion($values['line_subtotal_tax'], $recurring_proportion); } // Calculate recurring totals, required for totals display correctly on cart and order page $woocommerce->cart->recurring_cart_contents_total = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->cart_contents_total, $recurring_proportion); $woocommerce->cart->recurring_discount_cart = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->discount_cart, $recurring_proportion); $woocommerce->cart->recurring_discount_total = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->discount_total, $recurring_proportion); $woocommerce->cart->recurring_subtotal = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->subtotal, $recurring_proportion); $woocommerce->cart->recurring_subtotal_ex_tax = WC_Subscriptions_Manager::get_amount_from_proportion($woocommerce->cart->subtotal_ex_tax, $recurring_proportion); $woocommerce->cart->recurring_taxes = array(); // Add non-shipping taxes foreach ($woocommerce->cart->taxes as $tax_id => $tax_amount) { $woocommerce->cart->recurring_taxes[$tax_id] = WC_Subscriptions_Manager::get_amount_from_proportion($tax_amount, $recurring_proportion); } // And shipping taxes foreach ($woocommerce->cart->shipping_taxes as $tax_id => $tax_amount) { $woocommerce->cart->recurring_taxes[$tax_id] = $tax_amount; } // Shipping only applies to recurring payments // Shipping only applies to recurring amounts, not the sign-up fee, so we'll add it in its entirety to the recurring amount later $total_sans_shipping = $total - $woocommerce->cart->shipping_tax_total - $woocommerce->cart->shipping_total; $total_ex_tax = $total_sans_shipping - $woocommerce->cart->tax_total; $recurring_total_ex_tax = WC_Subscriptions_Manager::get_amount_from_proportion($total_ex_tax, $recurring_proportion) + $woocommerce->cart->shipping_total; $woocommerce->cart->recurring_total = WC_Subscriptions_Manager::get_amount_from_proportion($total_sans_shipping, $recurring_proportion) + $woocommerce->cart->shipping_tax_total + $woocommerce->cart->shipping_total; $woocommerce->cart->recurring_tax_total = $woocommerce->cart->recurring_total - $recurring_total_ex_tax; /** Handle pricing adjustments - Recurring / Sign up fee discounts / trial periods */ // Recurring discount if (WC_Subscriptions_Coupon::cart_contains_recurring_discount()) { // save cart with combined totals $original_cart = clone $woocommerce->cart; // calculate total with sign up fee only first self::$recalculation_type = 'sign_up_fee'; $woocommerce->cart->calculate_totals(); // save cart with just sign up fee $sign_up_fee_cart = clone $woocommerce->cart; // now calculate base recurring fee with discount included self::$recalculation_type = 'base_recurring_fee'; $woocommerce->cart->calculate_totals(); if (self::cart_contains_free_trial()) { // restore sign up fee cart contents & total $woocommerce->cart->cart_contents = $sign_up_fee_cart->cart_contents; $woocommerce->cart->cart_contents_total = $sign_up_fee_cart->cart_contents_total; // restore sign up fee cart sub-totals $woocommerce->cart->subtotal = $sign_up_fee_cart->subtotal; $woocommerce->cart->subtotal_ex_tax = $sign_up_fee_cart->subtotal_ex_tax; // restore sign up fee cart taxes $woocommerce->cart->taxes = $sign_up_fee_cart->taxes; $woocommerce->cart->tax_total = $sign_up_fee_cart->tax_total; // final total is sign up fee cart total only $total = $sign_up_fee_cart->total; // Add sign up fee discounts to cart/total discounts (which already include recurring discounts) $woocommerce->cart->discount_cart = $sign_up_fee_cart->discount_cart > 0 ? $sign_up_fee_cart->discount_cart : 0; $woocommerce->cart->discount_total = $sign_up_fee_cart->discount_total > 0 ? $sign_up_fee_cart->discount_total : 0; } else { // restore combined cart contents & total $woocommerce->cart->cart_contents = $original_cart->cart_contents; $woocommerce->cart->cart_contents_total = $original_cart->cart_contents_total; // restore combined cart sub-totals $woocommerce->cart->subtotal = $original_cart->subtotal; $woocommerce->cart->subtotal_ex_tax = $original_cart->subtotal_ex_tax; // combine and total any taxes on sign up fees to the cart total (which already includes taxes on recurring fees) foreach ($woocommerce->cart->taxes as $tax_key => $tax_amount) { $woocommerce->cart->taxes[$tax_key] += $sign_up_fee_cart->taxes[$tax_key]; } $woocommerce->cart->tax_total += $sign_up_fee_cart->tax_total; // Add sign up fee discounts to cart/total discounts (which already include recurring discounts) $woocommerce->cart->discount_cart += $sign_up_fee_cart->discount_cart > 0 ? $sign_up_fee_cart->discount_cart : 0; $woocommerce->cart->discount_total += $sign_up_fee_cart->discount_total > 0 ? $sign_up_fee_cart->discount_total : 0; // Final total is sign up fee cart total + recurring fee cart total $total = $sign_up_fee_cart->total + $woocommerce->cart->recurring_total; } // Sign up fee discount } elseif (WC_Subscriptions_Coupon::cart_contains_sign_up_discount()) { // save cart with combined totals $original_cart = clone $woocommerce->cart; // calculate totals with sign up fee only first self::$recalculation_type = 'sign_up_fee'; $woocommerce->cart->calculate_totals(); if (self::cart_contains_free_trial()) { // only need sign up total for the initial payment $total = $woocommerce->cart->total; } else { // restore combined cart contents & total $woocommerce->cart->cart_contents = $original_cart->cart_contents; $woocommerce->cart->cart_contents_total = $original_cart->cart_contents_total; // restore combined cart sub-totals $woocommerce->cart->subtotal = $original_cart->subtotal; $woocommerce->cart->subtotal_ex_tax = $original_cart->subtotal_ex_tax; $total = $woocommerce->cart->total + $woocommerce->cart->recurring_total; } // Free trial with no discounts - recalculate all the initial payment amounts just for the sign-up fee } elseif (self::cart_contains_free_trial()) { // only pass sign up fee thru get_price filters self::$recalculation_type = 'sign_up_fee'; $woocommerce->cart->calculate_totals(); // Make the sign up fee only total persist $total = $woocommerce->cart->total; } } return $total; }