/** * Restores discount coupons which had been removed for special subscription calculations. * * @since 1.3.5 */ public static function restore_coupons($cart) { global $woocommerce; if (!empty(self::$removed_coupons)) { // Can't use $cart->add_dicount here as it calls calculate_totals() $woocommerce->cart->applied_coupons = array_merge($woocommerce->cart->applied_coupons, self::$removed_coupons); self::$removed_coupons = array(); } }
/** * Restores discount coupons which had been removed for special subscription calculations. * * @since 1.3.5 */ public static function restore_coupons($cart) { _deprecated_function(__METHOD__, '2.0'); if (!empty(self::$removed_coupons)) { // Can't use $cart->add_dicount here as it calls calculate_totals() $cart->applied_coupons = array_merge($cart->applied_coupons, self::$removed_coupons); if (isset($cart->coupons)) { // WC 2.3+ $cart->coupons = $cart->get_coupons(); } self::$removed_coupons = array(); } }
/** * Check is a subscription coupon is valid before applying * * * @since 1.2 */ public static function validate_subscription_coupon($valid, $coupon) { // only check subscription coupons if (!in_array($coupon->type, array('recurring_fee', 'sign_up_fee'))) { return $valid; } // prevent subscription coupons from being applied to non-subscription products if (!WC_Subscriptions_Cart::cart_contains_subscription()) { $valid = false; self::$coupon_error = __('This coupon is only valid for subscriptions.', WC_Subscriptions::$text_domain); add_filter('woocommerce_coupon_error', __CLASS__ . '::add_coupon_error', 10); } // prevent sign up fee coupons from being applied to subscriptions without a sign up fee if (0 == WC_Subscriptions_Cart::get_cart_subscription_sign_up_fee() && 'sign_up_fee' == $coupon->type) { $valid = false; self::$coupon_error = __('This coupon is only valid for subscriptions with a sign-up fee.', WC_Subscriptions::$text_domain); add_filter('woocommerce_coupon_error', __CLASS__ . '::add_coupon_error', 10); } return $valid; }
/** * 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; }
/** * Function to apply Gift Certificate's credit to cart */ public function apply_smart_coupon_to_cart() { $this->global_wc()->cart->smart_coupon_credit_used = array(); $cart_contains_subscription = $this->is_cart_contains_subscription(); if ($cart_contains_subscription) { $calculation_type = WC_Subscriptions_Cart::get_calculation_type(); if ($calculation_type == 'recurring_total') { return; } } if ($this->global_wc()->cart->applied_coupons) { foreach ($this->global_wc()->cart->applied_coupons as $code) { $smart_coupon = new WC_Coupon($code); if ($smart_coupon->is_valid() && $smart_coupon->discount_type == 'smart_coupon') { $order_total = $this->global_wc()->cart->cart_contents_total + $this->global_wc()->cart->tax_total + $this->global_wc()->cart->shipping_tax_total + $this->global_wc()->cart->shipping_total; if ($this->global_wc()->cart->discount_total != 0 && $this->global_wc()->cart->discount_total + $smart_coupon->amount > $order_total) { $smart_coupon->amount = $order_total - $this->global_wc()->cart->discount_total; } elseif ($smart_coupon->amount > $order_total) { $smart_coupon->amount = $order_total; } $this->global_wc()->cart->discount_total = $this->global_wc()->cart->discount_total + $smart_coupon->amount; if ($cart_contains_subscription) { if ($this->is_wcs_gte('2.0.0')) { WC_Subscriptions_Coupon::increase_coupon_discount_amount($this->global_wc()->cart, $code, $smart_coupon->amount); } else { WC_Subscriptions_Cart::increase_coupon_discount_amount($code, $smart_coupon->amount); } } $this->global_wc()->cart->smart_coupon_credit_used[$code] = $smart_coupon->amount; //Code for displaying the price label for the store credit coupons if (empty($this->global_wc()->cart->coupon_discount_amounts)) { $this->global_wc()->cart->coupon_discount_amounts = array(); } $this->global_wc()->cart->coupon_discount_amounts[$code] = $smart_coupon->amount; } } } }