/**
  * Show the subscription template when view a subscription instead of loading the default order template.
  *
  * @param $located
  * @param $template_name
  * @param $args
  * @param $template_path
  * @param $default_path
  * @since 2.0
  */
 public static function add_view_subscription_template($located, $template_name, $args, $template_path, $default_path)
 {
     global $wp;
     if ('myaccount/my-account.php' == $template_name && !empty($wp->query_vars['view-subscription']) && WC_Subscriptions::is_woocommerce_pre('2.6')) {
         $located = wc_locate_template('myaccount/view-subscription.php', $template_path, plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/');
     }
     return $located;
 }
 /**
  * Create a simple subscription product object.
  *
  * @access public
  * @param mixed $product
  */
 public function __construct($product, $args = array())
 {
     parent::__construct($product, $args = array());
     $this->parent_product_type = $this->product_type;
     $this->product_type = 'subscription_variation';
     $this->subscription_variation_level_meta_data = array('subscription_price' => 0, 'subscription_period' => '', 'subscription_period_interval' => 'day', 'subscription_length' => 0, 'subscription_trial_length' => 0, 'subscription_trial_period' => 'day', 'subscription_sign_up_fee' => 0, 'subscription_payment_sync_date' => 0);
     if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
         // WC 2.1
         // Convert selected subscription meta fields for easy access
         foreach ($this->subscription_variation_level_meta_data as $meta_key => $default_value) {
             if (!empty($this->product_custom_fields['_' . $meta_key][0])) {
                 $this->{$meta_key} = maybe_unserialize($this->product_custom_fields['_' . $meta_key][0]);
             } else {
                 $this->{$meta_key} = $this->subscription_variation_level_meta_data[$meta_key];
             }
         }
     } else {
         $this->variation_level_meta_data = array_merge($this->variation_level_meta_data, $this->subscription_variation_level_meta_data);
     }
 }
 /**
  * When a new order is inserted, add subscriptions related order meta.
  *
  * @since 1.0
  */
 public static function add_order_meta($order_id, $posted)
 {
     global $woocommerce;
     if (!WC_Subscriptions_Cart::cart_contains_subscription_renewal('child') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         // This works because the 'woocommerce_add_order_item_meta' runs before the 'woocommerce_checkout_update_order_meta' hook
         // Set the recurring totals so totals display correctly on order page
         update_post_meta($order_id, '_order_recurring_discount_cart', WC_Subscriptions_Cart::get_recurring_discount_cart());
         update_post_meta($order_id, '_order_recurring_discount_cart_tax', WC_Subscriptions_Cart::get_recurring_discount_cart_tax());
         update_post_meta($order_id, '_order_recurring_discount_total', WC_Subscriptions_Cart::get_recurring_discount_total());
         update_post_meta($order_id, '_order_recurring_shipping_tax_total', WC_Subscriptions_Cart::get_recurring_shipping_tax_total());
         update_post_meta($order_id, '_order_recurring_shipping_total', WC_Subscriptions_Cart::get_recurring_shipping_total());
         update_post_meta($order_id, '_order_recurring_tax_total', WC_Subscriptions_Cart::get_recurring_total_tax());
         update_post_meta($order_id, '_order_recurring_total', WC_Subscriptions_Cart::get_recurring_total());
         // Set the recurring payment method - it starts out the same as the original by may change later
         update_post_meta($order_id, '_recurring_payment_method', get_post_meta($order_id, '_payment_method', true));
         update_post_meta($order_id, '_recurring_payment_method_title', get_post_meta($order_id, '_payment_method_title', true));
         $order = new WC_Order($order_id);
         $order_fees = $order->get_fees();
         // the fee order items have already been set, we just need to to add the recurring total meta
         $cart_fees = $woocommerce->cart->get_fees();
         foreach ($order->get_fees() as $item_id => $order_fee) {
             // Find the matching fee in the cart
             foreach ($cart_fees as $fee_index => $cart_fee) {
                 if (sanitize_title($order_fee['name']) == $cart_fee->id) {
                     woocommerce_add_order_item_meta($item_id, '_recurring_line_total', wc_format_decimal($cart_fee->recurring_amount));
                     woocommerce_add_order_item_meta($item_id, '_recurring_line_tax', wc_format_decimal($cart_fee->recurring_tax));
                     unset($cart_fees[$fee_index]);
                     break;
                 }
             }
         }
         // Get recurring taxes into same format as _order_taxes
         $order_recurring_taxes = array();
         foreach (WC_Subscriptions_Cart::get_recurring_taxes() as $tax_key => $tax_amount) {
             $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => WC_Tax::get_rate_code($tax_key), 'order_item_type' => 'recurring_tax'));
             if ($item_id) {
                 wc_add_order_item_meta($item_id, 'rate_id', $tax_key);
                 wc_add_order_item_meta($item_id, 'label', WC_Tax::get_rate_label($tax_key));
                 wc_add_order_item_meta($item_id, 'compound', absint(WC_Tax::is_compound($tax_key) ? 1 : 0));
                 wc_add_order_item_meta($item_id, 'tax_amount', wc_format_decimal(isset(WC()->cart->recurring_taxes[$tax_key]) ? WC()->cart->recurring_taxes[$tax_key] : 0));
                 wc_add_order_item_meta($item_id, 'shipping_tax_amount', wc_format_decimal(isset(WC()->cart->recurring_shipping_taxes[$tax_key]) ? WC()->cart->recurring_shipping_taxes[$tax_key] : 0));
             }
         }
         $payment_gateways = $woocommerce->payment_gateways->payment_gateways();
         if ('yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
             update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true');
         } elseif (isset($payment_gateways[$posted['payment_method']]) && !$payment_gateways[$posted['payment_method']]->supports('subscriptions')) {
             update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true');
         }
         $cart_item = WC_Subscriptions_Cart::cart_contains_subscription_renewal();
         if (isset($cart_item['subscription_renewal']) && 'parent' == $cart_item['subscription_renewal']['role']) {
             update_post_meta($order_id, '_original_order', $cart_item['subscription_renewal']['original_order']);
         }
         // WC 2.1+
         if (!WC_Subscriptions::is_woocommerce_pre('2.1')) {
             // Recurring coupons
             if ($applied_coupons = $woocommerce->cart->get_coupons()) {
                 foreach ($applied_coupons as $code => $coupon) {
                     if (!isset($woocommerce->cart->recurring_coupon_discount_amounts[$code])) {
                         continue;
                     }
                     $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $code, 'order_item_type' => 'recurring_coupon'));
                     // Add line item meta
                     if ($item_id) {
                         woocommerce_add_order_item_meta($item_id, 'discount_amount', isset($woocommerce->cart->recurring_coupon_discount_amounts[$code]) ? $woocommerce->cart->recurring_coupon_discount_amounts[$code] : 0);
                     }
                 }
             }
             // Add recurring shipping order items
             if (WC_Subscriptions_Cart::cart_contains_subscriptions_needing_shipping()) {
                 $packages = $woocommerce->shipping->get_packages();
                 $checkout = $woocommerce->checkout();
                 foreach ($packages as $i => $package) {
                     if (isset($package['rates'][$checkout->shipping_methods[$i]])) {
                         $method = $package['rates'][$checkout->shipping_methods[$i]];
                         $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $method->label, 'order_item_type' => 'recurring_shipping'));
                         if ($item_id) {
                             woocommerce_add_order_item_meta($item_id, 'method_id', $method->id);
                             woocommerce_add_order_item_meta($item_id, 'cost', WC_Subscriptions::format_total($method->cost));
                             woocommerce_add_order_item_meta($item_id, 'taxes', array_map('wc_format_decimal', $method->taxes));
                             do_action('woocommerce_subscriptions_add_recurring_shipping_order_item', $order_id, $item_id, $i);
                         }
                     }
                 }
             }
             // Remove shipping on original order if it was added but is not required
             if (!WC_Subscriptions_Cart::charge_shipping_up_front()) {
                 foreach ($order->get_shipping_methods() as $order_item_id => $shipping_method) {
                     woocommerce_update_order_item_meta($order_item_id, 'cost', WC_Subscriptions::format_total(0));
                 }
             }
         } else {
             update_post_meta($order_id, '_recurring_shipping_method', get_post_meta($order_id, '_shipping_method', true), true);
             update_post_meta($order_id, '_recurring_shipping_method_title', get_post_meta($order_id, '_shipping_method_title', true), true);
         }
     }
 }
 /**
  * Check if a renewal order subscription has any coupons applied and if so add pseudo renewal coupon equivalents to ensure the discount is still applied
  *
  * @param object $subscription subscription
  * @since 2.0.10
  */
 public function maybe_setup_discounts($subscription)
 {
     if (wcs_is_subscription($subscription)) {
         $used_coupons = $subscription->get_used_coupons();
         // Add any used coupon discounts to the cart (as best we can) using our pseudo renewal coupons
         if (!empty($used_coupons)) {
             $coupon_items = $subscription->get_items('coupon');
             foreach ($coupon_items as $coupon_item) {
                 $coupon = new WC_Coupon($coupon_item['name']);
                 $coupon_code = '';
                 // If the coupon still exists we can use the existing/available coupon properties
                 if (true === $coupon->exists) {
                     // But we only want to handle recurring coupons that have been applied to the subscription
                     if (in_array($coupon->type, array('recurring_percent', 'recurring_fee'))) {
                         // Set the coupon type to be a renewal equivalent for correct validation and calculations
                         if ('recurring_percent' == $coupon->type) {
                             $coupon->type = 'renewal_percent';
                         } elseif ('recurring_fee' == $coupon->type) {
                             $coupon->type = 'renewal_fee';
                         }
                         // Adjust coupon code to reflect that it is being applied to a renewal
                         $coupon_code = $coupon->code;
                     }
                 } else {
                     // If the coupon doesn't exist we can only really apply the discount amount we know about - so we'll apply a cart style pseudo coupon and then set the amount
                     $coupon->type = 'renewal_cart';
                     $coupon->amount = $coupon_item['item_meta']['discount_amount']['0'];
                     // Adjust coupon code to reflect that it is being applied to a renewal
                     $coupon_code = $coupon->code;
                 }
                 // Now that we have a coupon we know we want to apply
                 if (!empty($coupon_code)) {
                     // Set renewal order products as the product ids on the coupon
                     if (!WC_Subscriptions::is_woocommerce_pre('2.5')) {
                         $coupon->product_ids = $this->get_products($subscription);
                     }
                     // Store the coupon info for later
                     $this->store_coupon($subscription->id, $coupon);
                     // Add the coupon to the cart - the actually coupon values / data are grabbed when needed later
                     if (WC()->cart && !WC()->cart->has_discount($coupon_code)) {
                         WC()->cart->add_discount($coupon_code);
                     }
                 }
             }
             // If there are no coupons but there is still a discount (i.e. it might have been manually added), we need to account for that as well
         } elseif (!empty($subscription->cart_discount)) {
             $coupon = new WC_Coupon('discount_renewal');
             // Apply our cart style pseudo coupon and the set the amount
             $coupon->type = 'renewal_cart';
             $coupon->amount = $subscription->cart_discount;
             // Set renewal order products as the product ids on the coupon
             if (!WC_Subscriptions::is_woocommerce_pre('2.5')) {
                 $coupon->product_ids = $this->get_products($subscription);
             }
             // Store the coupon info for later
             $this->store_coupon($subscription->id, $coupon);
             // Add the coupon to the cart
             if (WC()->cart && !WC()->cart->has_discount('discount_renewal')) {
                 WC()->cart->add_discount('discount_renewal');
             }
         }
     }
 }
 /**
  * Save variation meta data when it is bulk edited from the Edit Product screen
  *
  * @param string $bulk_action The bulk edit action being performed
  * @param array $data An array of data relating to the bulk edit action. $data['value'] represents the new value for the meta.
  * @param int $variable_product_id The post ID of the parent variable product.
  * @param array $variation_ids An array of post IDs for the variable prodcut's variations.
  * @since 1.5.29
  */
 public static function bulk_edit_variations($bulk_action, $data, $variable_product_id, $variation_ids)
 {
     if (!isset($data['value'])) {
         return;
     } elseif (WC_Subscriptions::is_woocommerce_pre('2.5')) {
         // Pre 2.5 we don't have the product type information available so we have to check if it is a subscription - downside here is this only works if the product has already been saved
         if (!self::is_subscription($variable_product_id)) {
             return;
         }
     } else {
         // Since 2.5 we have the product type information available so we don't have to wait for the product to be saved to check if it is a subscription
         if (empty($_POST['security']) || !wp_verify_nonce($_POST['security'], 'bulk-edit-variations') || 'variable-subscription' !== $_POST['product_type']) {
             return;
         }
     }
     $meta_key = str_replace('variable', '', $bulk_action);
     // Update the subscription price when updating regular price on a variable subscription product
     if ('_regular_price' == $meta_key) {
         $meta_key = '_subscription_price';
     }
     if (in_array($meta_key, self::$subscription_meta_fields)) {
         foreach ($variation_ids as $variation_id) {
             update_post_meta($variation_id, $meta_key, stripslashes($data['value']));
         }
     } elseif (in_array($meta_key, array('_regular_price_increase', '_regular_price_decrease'))) {
         $operator = '_regular_price_increase' == $meta_key ? '+' : '-';
         $value = wc_clean($data['value']);
         foreach ($variation_ids as $variation_id) {
             $subscription_price = get_post_meta($variation_id, '_subscription_price', true);
             if ('%' === substr($value, -1)) {
                 $percent = wc_format_decimal(substr($value, 0, -1));
                 $subscription_price += $subscription_price / 100 * $percent * "{$operator}1";
             } else {
                 $subscription_price += $value * "{$operator}1";
             }
             update_post_meta($variation_id, '_subscription_price', $subscription_price);
         }
     }
 }
 /**
  * Save variation meta data when it is bulk edited from the Edit Product screen
  *
  * @param string $bulk_action The bulk edit action being performed
  * @param array $data An array of data relating to the bulk edit action. $data['value'] represents the new value for the meta.
  * @param int $variable_product_id The post ID of the parent variable product.
  * @param array $variation_ids An array of post IDs for the variable prodcut's variations.
  * @since 1.5.29
  */
 public static function bulk_edit_variations($bulk_action, $data, $variable_product_id, $variation_ids)
 {
     if (WC_Subscriptions::is_woocommerce_pre('2.5')) {
         // Pre 2.5 we don't have the product type information available so we have to check if it is a subscription - downside here is this only works if the product has already been saved
         if (!self::is_subscription($variable_product_id)) {
             return;
         }
     } else {
         // Since 2.5 we have the product type information available so we don't have to wait for the product to be saved to check if it is a subscription
         if (empty($_POST['security']) || !wp_verify_nonce($_POST['security'], 'bulk-edit-variations') || 'variable-subscription' !== $_POST['product_type']) {
             return;
         }
     }
     $meta_key = str_replace('variable', '', $bulk_action);
     // Update the subscription price when updating regular price on a variable subscription product
     if ('_regular_price' == $meta_key) {
         $meta_key = '_subscription_price';
     }
     if (in_array($meta_key, self::$subscription_meta_fields)) {
         foreach ($variation_ids as $variation_id) {
             update_post_meta($variation_id, $meta_key, stripslashes($data['value']));
         }
     }
 }
 /**
  * Generate an order items table using a WC compatible version of the function.
  *
  * @param object $order
  * @param array $args {
  *     @type bool  'show_download_links'
  *     @type bool  'show_sku'
  *     @type bool  'show_purchase_note'
  *     @type array 'image_size'
  *     @type bool  'plain_text'
  * }
  * @return string email order items table html
  */
 public static function email_order_items_table($order, $args = array())
 {
     $items_table = '';
     if (is_numeric($order)) {
         $order = wc_get_order($order);
     }
     if (is_a($order, 'WC_Abstract_Order')) {
         if (WC_Subscriptions::is_woocommerce_pre('2.5')) {
             $items_table = call_user_func_array(array($order, 'email_order_items_table'), $args);
         } else {
             // 2.5 doesn't support both the show_download_links or show_purchase_note parameters but uses $order->is_download_permitted and  $order->is_paid instead
             $show_download_links_callback = isset($args['show_download_links']) && $args['show_download_links'] ? '__return_true' : '__return_false';
             $show_purchase_note_callback = isset($args['show_purchase_note']) && $args['show_purchase_note'] ? '__return_true' : '__return_false';
             unset($args['show_download_links']);
             unset($args['show_purchase_note']);
             add_filter('woocommerce_order_is_download_permitted', $show_download_links_callback);
             add_filter('woocommerce_order_is_paid', $show_purchase_note_callback);
             $items_table = $order->email_order_items_table($args);
             remove_filter('woocommerce_order_is_download_permitted', $show_download_links_callback);
             remove_filter('woocommerce_order_is_paid', $show_purchase_note_callback);
         }
     }
     return $items_table;
 }
 /**
  * Add the sync setting fields to the variation section of the Edit Product screen
  *
  * @since 1.5
  */
 public static function variable_subscription_product_fields($loop, $variation_data, $variation)
 {
     if (self::is_syncing_enabled()) {
         // Set month as the default billing period
         if (!($subscription_period = get_post_meta($variation->ID, '_subscription_period', true))) {
             $subscription_period = 'month';
         }
         $display_week_month_select = !in_array($subscription_period, array('month', 'week')) ? ' style="display: none;"' : '';
         $display_annual_select = 'year' != $subscription_period ? ' style="display: none;"' : '';
         $payment_day = self::get_products_payment_day($variation->ID);
         // An annual sync date is already set in the form: array( 'day' => 'nn', 'month' => 'nn' ), create a MySQL string from those values (year and time are irrelvent as they are ignored)
         if (is_array($payment_day)) {
             $payment_month = $payment_day['month'];
             $payment_day = $payment_day['day'];
         } else {
             $payment_month = date('m');
         }
         if (WC_Subscriptions::is_woocommerce_pre('2.3')) {
             include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/deprecated/html-variation-synchronisation.php';
         } else {
             include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/html-variation-synchronisation.php';
         }
     }
 }
 /**
  * If the order is a renewal order, don't send core emails.
  *
  * @param int $user_id The ID of the user who the subscription belongs to
  * @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
  * @return void
  */
 public static function maybe_reattach_woocommerce_email($order_id)
 {
     global $woocommerce;
     if (WC_Subscriptions_Renewal_Order::is_renewal($order_id, array('order_role' => 'child')) || WC_Subscriptions_Switcher::order_contains_subscription_switch($order_id)) {
         if (WC_Subscriptions::is_woocommerce_pre('2.3')) {
             add_action(current_filter(), array($woocommerce, 'send_transactional_email'));
         } else {
             add_action(current_filter(), array('WC_Emails', 'send_transactional_email'));
         }
     }
 }
 /**
  * Set the chosen shipping method for recurring cart calculations
  *
  * In WC_Shipping::calculate_shipping(), WooCommerce tries to determine the chosen shipping method
  * based on the package index and stores rates. However, for recurring cart shipping selection, we
  * use the recurring cart key instead of numeric index. Therefore, we need to hook in to override
  * the default shipping method when WooCommerce could not find a matching shipping method.
  *
  * @param string $default_method the default shipping method for the customer/store returned by WC_Shipping::get_default_method()
  * @param array $available_methods set of shipping rates for this calculation
  * @param int $package_index WC doesn't pass the package index to callbacks on the 'woocommerce_shipping_chosen_method' filter (yet) so we set a default value of 0 for it in the function params
  * @since 2.0.12
  */
 public static function set_chosen_shipping_method($default_method, $available_methods, $package_index = 0)
 {
     $chosen_methods = WC()->session->get('chosen_shipping_methods');
     $recurring_cart_package_key = self::get_recurring_shipping_package_key(self::$recurring_cart_key, $package_index);
     if ('none' !== self::$recurring_cart_key && isset($chosen_methods[$recurring_cart_package_key]) && isset($available_methods[$chosen_methods[$recurring_cart_package_key]])) {
         $default_method = $chosen_methods[$recurring_cart_package_key];
         // Our dummy rate ended up being set as the default method (probably because it has no priority) so we need to re-run some logic from WC_Shipping::get_default_method() to find the actual default method
     } elseif ('wcs_dummy_rate' === $default_method && !empty($available_methods)) {
         unset($available_methods['wcs_dummy_rate']);
         // Order by priorities and costs
         $selection_priority = get_option('woocommerce_shipping_method_selection_priority', array());
         $prioritized_methods = array();
         foreach ($available_methods as $method_key => $method) {
             // Some IDs contain : if they have multiple rates so use $method->method_id
             $priority = isset($selection_priority[$method->method_id]) ? absint($selection_priority[$method->method_id]) : 1;
             if (empty($prioritized_methods[$priority])) {
                 $prioritized_methods[$priority] = array();
             }
             $prioritized_methods[$priority][$method_key] = $method->cost;
         }
         ksort($prioritized_methods);
         $prioritized_methods = current($prioritized_methods);
         asort($prioritized_methods);
         $default_method = current(array_keys($prioritized_methods));
         // Set the chosen shipping method (if available) to workaround a bug with WC_Shipping::get_default_method() in WC < 2.6 which leads to the default shipping method always being used instead of a valid chosen shipping method
     } elseif (isset($chosen_methods[$package_index]) && $default_method !== $chosen_methods[$package_index] && WC_Subscriptions::is_woocommerce_pre('2.6')) {
         $default_method = $chosen_methods[$package_index];
     }
     return $default_method;
 }
    /**
     * Prompt the store manager to enter their PayPal API credentials if they are using
     * PayPal and have yet not entered their API credentials.
     *
     * @return void
     */
    public static function maybe_show_admin_notice()
    {
        if (isset($_GET['wcs_disable_paypal_invalid_profile_id_notice'])) {
            update_option('wcs_paypal_invalid_profile_id', 'disabled');
        }
        // Check if the API credentials are being saved - we can't do this on the 'woocommerce_update_options_payment_gateways_paypal' hook because it is triggered after 'admin_notices'
        if (isset($_POST['woocommerce_paypal_api_username']) || isset($_POST['woocommerce_paypal_api_password']) || isset($_POST['woocommerce_paypal_api_signature'])) {
            $current_options = self::get_wc_paypal_settings();
            $credentials_updated = false;
            if (isset($_POST['woocommerce_paypal_api_username']) && $_POST['woocommerce_paypal_api_username'] != $current_options['api_username']) {
                $credentials_updated = true;
            } elseif (isset($_POST['woocommerce_paypal_api_password']) && $_POST['woocommerce_paypal_api_password'] != $current_options['api_password']) {
                $credentials_updated = true;
            } elseif (isset($_POST['woocommerce_paypal_api_signature']) && $_POST['woocommerce_paypal_api_signature'] != $current_options['api_signature']) {
                $credentials_updated = true;
            }
            if ($credentials_updated) {
                delete_option('wcs_paypal_credentials_error');
            }
        }
        if (!in_array(get_woocommerce_currency(), apply_filters('woocommerce_paypal_supported_currencies', array('AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB')))) {
            $valid_for_use = false;
        } else {
            $valid_for_use = true;
        }
        if (WC_Subscriptions::is_woocommerce_pre('2.1')) {
            $payment_gateway_tab_url = admin_url('admin.php?page=woocommerce_settings&tab=payment_gateways&section=WC_Gateway_Paypal');
        } else {
            $payment_gateway_tab_url = admin_url('admin.php?page=wc-settings&tab=checkout&section=wc_gateway_paypal');
        }
        if (!self::are_credentials_set() && $valid_for_use && 'yes' == self::$paypal_settings['enabled'] && !has_action('admin_notices', 'WC_Subscriptions_Admin::admin_installed_notice') && current_user_can('manage_options')) {
            ?>
<div id="message" class="updated error">
	<p><?php 
            printf(__('PayPal is inactive for subscription transactions. Please %sset up the PayPal IPN%s and %senter your API credentials%s to enable PayPal for Subscriptions.', 'woocommerce-subscriptions'), '<a href="http://docs.woothemes.com/document/subscriptions/store-manager-guide/#section-4" target="_blank">', '</a>', '<a href="' . $payment_gateway_tab_url . '">', '</a>');
            ?>
	</p>
</div>
<?php 
        }
        if (false !== get_option('wcs_paypal_credentials_error')) {
            ?>
<div id="message" class="updated error">
	<p><?php 
            printf(__('There is a problem with PayPal. Your API credentials may be incorrect. Please update your %sAPI credentials%s. %sLearn more%s.', 'woocommerce-subscriptions'), '<a href="' . $payment_gateway_tab_url . '">', '</a>', '<a href="https://support.woothemes.com/hc/en-us/articles/202882473#paypal-credentials" target="_blank">', '</a>');
            ?>
	</p>
</div>
<?php 
        }
        if ('yes' == get_option('wcs_paypal_invalid_profile_id')) {
            ?>
<div id="message" class="updated error">
	<p><?php 
            printf(__('There is a problem with PayPal. Your PayPal account is issuing out-of-date subscription IDs. %sLearn more%s. %sDismiss%s.', 'woocommerce-subscriptions'), '<a href="https://support.woothemes.com/hc/en-us/articles/202882473#old-paypal-account" target="_blank">', '</a>', '<a href="' . esc_url(add_query_arg('wcs_disable_paypal_invalid_profile_id_notice', 'true')) . '">', '</a>');
            ?>
	</p>
</div>
<?php 
        }
    }
 /**
  * Version 1.2 introduced a massive change to the order meta data schema. This function goes
  * through and upgrades the existing data on all orders to the new schema.
  *
  * The upgrade process is timeout safe as it keeps a record of the orders upgraded and only
  * deletes this record once all orders have been upgraded successfully. If operating on a huge
  * number of orders and the upgrade process times out, only the orders not already upgraded
  * will be upgraded in future requests that trigger this function.
  *
  * @since 1.2
  */
 private static function upgrade_database_to_1_2()
 {
     global $wpdb;
     // Get IDs only and use a direct DB query for efficiency
     $orders_to_upgrade = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order' AND post_parent = 0");
     $upgraded_orders = get_option('wcs_1_2_upgraded_order_ids', array());
     // Transition deprecated subscription status if we aren't in the middle of updating orders
     if (empty($upgraded_orders)) {
         $wpdb->query($wpdb->prepare("UPDATE {$wpdb->usermeta} SET meta_value = replace( meta_value, 's:9:\"suspended\"', 's:7:\"on-hold\"' ) WHERE meta_key LIKE %s", '%_woocommerce_subscriptions'));
         $wpdb->query($wpdb->prepare("UPDATE {$wpdb->usermeta} SET meta_value = replace( meta_value, 's:6:\"failed\"', 's:9:\"cancelled\"' ) WHERE meta_key LIKE %s", '%_woocommerce_subscriptions'));
     }
     $orders_to_upgrade = array_diff($orders_to_upgrade, $upgraded_orders);
     // Upgrade all _sign_up_{field} order meta to new order data format
     foreach ($orders_to_upgrade as $order_id) {
         $order = new WC_Order($order_id);
         // Manually check if a product in an order is a subscription, we can't use WC_Subscriptions_Order::order_contains_subscription( $order ) because it relies on the new data structure
         $contains_subscription = false;
         foreach ($order->get_items() as $order_item) {
             if (WC_Subscriptions_Product::is_subscription(WC_Subscriptions_Order::get_items_product_id($order_item))) {
                 $contains_subscription = true;
                 break;
             }
         }
         if (!$contains_subscription) {
             continue;
         }
         $trial_lengths = WC_Subscriptions_Order::get_meta($order, '_order_subscription_trial_lengths', array());
         $trial_length = array_pop($trial_lengths);
         $has_trial = !empty($trial_length) && $trial_length > 0 ? true : false;
         $sign_up_fee_total = WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_total', 0);
         // Create recurring_* meta data from existing cart totals
         $cart_discount = $order->get_cart_discount();
         update_post_meta($order_id, '_order_recurring_discount_cart', $cart_discount);
         $order_discount = $order->get_order_discount();
         update_post_meta($order_id, '_order_recurring_discount_total', $order_discount);
         $order_shipping_tax = get_post_meta($order_id, '_order_shipping_tax', true);
         update_post_meta($order_id, '_order_recurring_shipping_tax_total', $order_shipping_tax);
         $order_tax = get_post_meta($order_id, '_order_tax', true);
         // $order->get_total_tax() includes shipping tax
         update_post_meta($order_id, '_order_recurring_tax_total', $order_tax);
         $order_total = $order->get_total();
         update_post_meta($order_id, '_order_recurring_total', $order_total);
         // Set order totals to include sign up fee fields, if there was a sign up fee on the order and a trial period (other wise, the recurring totals are correct)
         if ($sign_up_fee_total > 0) {
             // Order totals need to be changed to be equal to sign up fee totals
             if ($has_trial) {
                 $cart_discount = WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_discount_cart', 0);
                 $order_discount = WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_discount_total', 0);
                 $order_tax = WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_tax_total', 0);
                 $order_total = $sign_up_fee_total;
             } else {
                 // No trial, sign up fees need to be added to order totals
                 $cart_discount += WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_discount_cart', 0);
                 $order_discount += WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_discount_total', 0);
                 $order_tax += WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_tax_total', 0);
                 $order_total += $sign_up_fee_total;
             }
             update_post_meta($order_id, '_order_total', $order_total);
             update_post_meta($order_id, '_cart_discount', $cart_discount);
             update_post_meta($order_id, '_order_discount', $order_discount);
             update_post_meta($order_id, '_order_tax', $order_tax);
         }
         // Make sure we get order taxes in WC 1.x format
         if (false == self::$is_wc_version_2) {
             $order_taxes = $order->get_taxes();
         } else {
             $order_tax_row = $wpdb->get_row($wpdb->prepare("\n\t\t\t\t\tSELECT * FROM {$wpdb->postmeta}\n\t\t\t\t\tWHERE meta_key = '_order_taxes_old'\n\t\t\t\t\tAND post_id = %s\n\t\t\t\t\t", $order_id));
             $order_taxes = (array) maybe_unserialize($order_tax_row->meta_value);
         }
         // Set recurring taxes to order taxes, if using WC 2.0, this will be migrated to the new format in @see self::upgrade_to_latest_wc()
         update_post_meta($order_id, '_order_recurring_taxes', $order_taxes);
         $sign_up_fee_taxes = WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_taxes', array());
         // Update order taxes to include sign up fee taxes
         foreach ($sign_up_fee_taxes as $index => $sign_up_tax) {
             if ($has_trial && $sign_up_fee_total > 0) {
                 // Order taxes need to be set to the same as the sign up fee taxes
                 if (isset($sign_up_tax['cart_tax']) && $sign_up_tax['cart_tax'] > 0) {
                     $order_taxes[$index]['cart_tax'] = $sign_up_tax['cart_tax'];
                 }
             } elseif (!$has_trial && $sign_up_fee_total > 0) {
                 // Sign up fee taxes need to be added to order taxes
                 if (isset($sign_up_tax['cart_tax']) && $sign_up_tax['cart_tax'] > 0) {
                     $order_taxes[$index]['cart_tax'] += $sign_up_tax['cart_tax'];
                 }
             }
         }
         if (false == self::$is_wc_version_2) {
             // Doing it right: updated Subs *before* updating WooCommerce, the WooCommerce updater will take care of data migration
             update_post_meta($order_id, '_order_taxes', $order_taxes);
         } else {
             // Doing it wrong: updated Subs *after* updating WooCommerce, need to store in WC2.0 tax structure
             $index = 0;
             $new_order_taxes = $order->get_taxes();
             foreach ($new_order_taxes as $item_id => $order_tax) {
                 $index = $index + 1;
                 if (!isset($order_taxes[$index]['label']) || !isset($order_taxes[$index]['cart_tax']) || !isset($order_taxes[$index]['shipping_tax'])) {
                     continue;
                 }
                 // Add line item meta
                 if ($item_id) {
                     woocommerce_update_order_item_meta($item_id, 'compound', absint(isset($order_taxes[$index]['compound']) ? $order_taxes[$index]['compound'] : 0));
                     woocommerce_update_order_item_meta($item_id, 'tax_amount', WC_Subscriptions::format_total($order_taxes[$index]['cart_tax']));
                     woocommerce_update_order_item_meta($item_id, 'shipping_tax_amount', WC_Subscriptions::format_total($order_taxes[$index]['shipping_tax']));
                 }
             }
         }
         /* Upgrade each order item to use new Item Meta schema */
         $order_subscription_periods = WC_Subscriptions_Order::get_meta($order_id, '_order_subscription_periods', array());
         $order_subscription_intervals = WC_Subscriptions_Order::get_meta($order_id, '_order_subscription_intervals', array());
         $order_subscription_lengths = WC_Subscriptions_Order::get_meta($order_id, '_order_subscription_lengths', array());
         $order_subscription_trial_lengths = WC_Subscriptions_Order::get_meta($order_id, '_order_subscription_trial_lengths', array());
         $order_items = $order->get_items();
         foreach ($order_items as $index => $order_item) {
             $product_id = WC_Subscriptions_Order::get_items_product_id($order_item);
             if (WC_Subscriptions::is_woocommerce_pre('2.4')) {
                 $item_meta = new WC_Order_Item_Meta($order_item['item_meta']);
             } else {
                 $item_meta = new WC_Order_Item_Meta($order_item);
             }
             $subscription_interval = isset($order_subscription_intervals[$product_id]) ? $order_subscription_intervals[$product_id] : 1;
             $subscription_length = isset($order_subscription_lengths[$product_id]) ? $order_subscription_lengths[$product_id] : 0;
             $subscription_trial_length = isset($order_subscription_trial_lengths[$product_id]) ? $order_subscription_trial_lengths[$product_id] : 0;
             $subscription_sign_up_fee = WC_Subscriptions_Order::get_meta($order, '_cart_contents_sign_up_fee_total', 0);
             if ($sign_up_fee_total > 0) {
                 // Discounted price * Quantity
                 $sign_up_fee_line_total = WC_Subscriptions_Order::get_meta($order, '_cart_contents_sign_up_fee_total', 0);
                 $sign_up_fee_line_tax = WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_tax_total', 0);
                 // Base price * Quantity
                 $sign_up_fee_line_subtotal = WC_Subscriptions_Order::get_meta($order, '_cart_contents_sign_up_fee_total', 0) + WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_discount_cart', 0);
                 $sign_up_fee_propotion = $sign_up_fee_line_total > 0 ? $sign_up_fee_line_subtotal / $sign_up_fee_line_total : 0;
                 $sign_up_fee_line_subtotal_tax = WC_Subscriptions_Manager::get_amount_from_proportion(WC_Subscriptions_Order::get_meta($order, '_sign_up_fee_tax_total', 0), $sign_up_fee_propotion);
                 if ($has_trial) {
                     // Set line item totals equal to sign up fee totals
                     $order_item['line_subtotal'] = $sign_up_fee_line_subtotal;
                     $order_item['line_subtotal_tax'] = $sign_up_fee_line_subtotal_tax;
                     $order_item['line_total'] = $sign_up_fee_line_total;
                     $order_item['line_tax'] = $sign_up_fee_line_tax;
                 } else {
                     // No trial period, sign up fees need to be added to order totals
                     $order_item['line_subtotal'] += $sign_up_fee_line_subtotal;
                     $order_item['line_subtotal_tax'] += $sign_up_fee_line_subtotal_tax;
                     $order_item['line_total'] += $sign_up_fee_line_total;
                     $order_item['line_tax'] += $sign_up_fee_line_tax;
                 }
             }
             // Upgrading with WC 1.x
             if (method_exists($item_meta, 'add')) {
                 $item_meta->add('_subscription_period', $order_subscription_periods[$product_id]);
                 $item_meta->add('_subscription_interval', $subscription_interval);
                 $item_meta->add('_subscription_length', $subscription_length);
                 $item_meta->add('_subscription_trial_length', $subscription_trial_length);
                 $item_meta->add('_subscription_recurring_amount', $order_item['line_subtotal']);
                 // WC_Subscriptions_Product::get_price() would return a price without filters applied
                 $item_meta->add('_subscription_sign_up_fee', $subscription_sign_up_fee);
                 // Set recurring amounts for the item
                 $item_meta->add('_recurring_line_total', $order_item['line_total']);
                 $item_meta->add('_recurring_line_tax', $order_item['line_tax']);
                 $item_meta->add('_recurring_line_subtotal', $order_item['line_subtotal']);
                 $item_meta->add('_recurring_line_subtotal_tax', $order_item['line_subtotal_tax']);
                 $order_item['item_meta'] = $item_meta->meta;
                 $order_items[$index] = $order_item;
             } else {
                 // Ignoring all advice, upgrading 4 months after version 1.2 was released, and doing it with WC 2.0 installed
                 woocommerce_add_order_item_meta($index, '_subscription_period', $order_subscription_periods[$product_id]);
                 woocommerce_add_order_item_meta($index, '_subscription_interval', $subscription_interval);
                 woocommerce_add_order_item_meta($index, '_subscription_length', $subscription_length);
                 woocommerce_add_order_item_meta($index, '_subscription_trial_length', $subscription_trial_length);
                 woocommerce_add_order_item_meta($index, '_subscription_trial_period', $order_subscription_periods[$product_id]);
                 woocommerce_add_order_item_meta($index, '_subscription_recurring_amount', $order_item['line_subtotal']);
                 woocommerce_add_order_item_meta($index, '_subscription_sign_up_fee', $subscription_sign_up_fee);
                 // Calculated recurring amounts for the item
                 woocommerce_add_order_item_meta($index, '_recurring_line_total', $order_item['line_total']);
                 woocommerce_add_order_item_meta($index, '_recurring_line_tax', $order_item['line_tax']);
                 woocommerce_add_order_item_meta($index, '_recurring_line_subtotal', $order_item['line_subtotal']);
                 woocommerce_add_order_item_meta($index, '_recurring_line_subtotal_tax', $order_item['line_subtotal_tax']);
                 if ($sign_up_fee_total > 0) {
                     // Order totals have changed
                     woocommerce_update_order_item_meta($index, '_line_subtotal', woocommerce_format_decimal($order_item['line_subtotal']));
                     woocommerce_update_order_item_meta($index, '_line_subtotal_tax', woocommerce_format_decimal($order_item['line_subtotal_tax']));
                     woocommerce_update_order_item_meta($index, '_line_total', woocommerce_format_decimal($order_item['line_total']));
                     woocommerce_update_order_item_meta($index, '_line_tax', woocommerce_format_decimal($order_item['line_tax']));
                 }
             }
         }
         // Save the new meta on the order items for WC 1.x (the API functions already saved the data for WC2.x)
         if (false == self::$is_wc_version_2) {
             update_post_meta($order_id, '_order_items', $order_items);
         }
         $upgraded_orders[] = $order_id;
         update_option('wcs_1_2_upgraded_order_ids', $upgraded_orders);
     }
 }
 /**
  * Parse recurring shipping rates from the front end and put them into the $_POST['shipping_method'] used by WooCommerce.
  *
  * When WooCommerce takes the value of inputs for shipping methods selection from the cart and checkout pages, it uses a
  * JavaScript array and therefore, can only use numerical indexes. This works for WC core, because it only needs shipping
  * selection for different packages. However, we want to use string indexes to differentiate between different recurring
  * cart shipping selection inputs *and* packages. To do this, we need to get our shipping methods from the $_POST['post_data']
  * values and manually add them $_POST['shipping_method'] array.
  *
  * We can't do this on the cart page unfortunately because it doesn't pass the entire forms post data and instead only
  * sends the shipping methods with a numerical index.
  *
  * @return null
  * @since 2.0.12
  */
 public static function add_shipping_method_post_data()
 {
     if (!WC_Subscriptions::is_woocommerce_pre('2.6')) {
         return;
     }
     check_ajax_referer('update-order-review', 'security');
     parse_str($_POST['post_data'], $form_data);
     // In case we have only free trials/sync'd products in the cart and shipping methods aren't being displayed
     if (!isset($_POST['shipping_method'])) {
         $_POST['shipping_method'] = array();
     }
     if (!isset($form_data['shipping_method'])) {
         $form_data['shipping_method'] = array();
     }
     foreach ($form_data['shipping_method'] as $key => $methods) {
         if (!is_numeric($key) && !array_key_exists($key, $_POST['shipping_method'])) {
             $_POST['shipping_method'][$key] = $methods;
         }
     }
 }
 /**
  * Restore renewal flag when cart is reset and modify Product object with
  * renewal order related info
  *
  * @since 1.3
  */
 public static function get_cart_item_from_session($session_data, $values, $key)
 {
     if (isset($values['subscription_renewal'])) {
         $session_data['subscription_renewal'] = $values['subscription_renewal'];
         // Need to get the original order price, not the current price
         $original_order_id = $values['subscription_renewal']['original_order'];
         $order_items = WC_Subscriptions_Order::get_recurring_items($original_order_id);
         $first_order_item = reset($order_items);
         $price = $first_order_item['subscription_recurring_amount'];
         /*
          * Modify the Cart $_product object.
          * All the cart calculations and cart/checkout/mini-cart displays will use this object.
          * So by modifying it here, we take care of all those cases.
          */
         $_product = $session_data['data'];
         $_product->price = $price;
         // Don't carry over any sign up fee
         $_product->subscription_sign_up_fee = 0;
         if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
             $_product->product_custom_fields['_subscription_sign_up_fee'][0] = 0;
         }
         // Make sure the original subscription terms perisist
         if ('parent' == $session_data['subscription_renewal']['role']) {
             $_product->subscription_price = $price;
             $_product->subscription_period = $first_order_item['subscription_period'];
             $_product->subscription_period_interval = $first_order_item['subscription_interval'];
             $_product->subscription_trial_period = $first_order_item['subscription_trial_period'];
             $_product->subscription_length = $first_order_item['subscription_length'];
             // Never give a free trial period again
             $_product->subscription_trial_length = 0;
             if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
                 $_product->product_custom_fields['_subscription_price'][0] = $price;
                 $_product->product_custom_fields['_subscription_period'][0] = $first_order_item['subscription_period'];
                 $_product->product_custom_fields['_subscription_period_interval'][0] = $first_order_item['subscription_interval'];
                 $_product->product_custom_fields['_subscription_trial_period'][0] = $first_order_item['subscription_trial_period'];
                 $_product->product_custom_fields['_subscription_length'][0] = $first_order_item['subscription_length'];
                 $_product->product_custom_fields['_subscription_trial_length'][0] = 0;
             }
         }
         $_product->post->post_title = apply_filters('woocommerce_subscriptions_renewal_product_title', $_product->get_title(), $_product);
         // Make sure the same quantity is renewed
         $session_data['quantity'] = $first_order_item['qty'];
     }
     return $session_data;
 }
 /**
  * Apply sign up fee or recurring fee discount
  *
  * @since 1.2
  */
 public static function apply_subscription_discount($original_price, $cart_item, $cart)
 {
     _deprecated_function(__METHOD__, '2.0.10', 'Have moved to filtering on "woocommerce_coupon_get_discount_amount" to return discount amount. See: ' . __CLASS__ . '::get_discount_amount()');
     $product_id = $cart_item['data']->is_type(array('subscription_variation')) ? $cart_item['data']->variation_id : $cart_item['data']->id;
     if (!WC_Subscriptions_Product::is_subscription($product_id)) {
         return $original_price;
     }
     $price = $calculation_price = $original_price;
     $calculation_type = WC_Subscriptions_Cart::get_calculation_type();
     if (!empty($cart->applied_coupons)) {
         foreach ($cart->applied_coupons as $code) {
             $coupon = new WC_Coupon($code);
             // Pre 2.5 is_valid_for_product() does not use wc_get_product_coupon_types()
             if (WC_Subscriptions::is_woocommerce_pre('2.5')) {
                 $is_valid_for_product = true;
             } else {
                 $is_valid_for_product = $coupon->is_valid_for_product(wc_get_product($product_id), $cart_item);
             }
             if ($coupon->apply_before_tax() && $coupon->is_valid() && $is_valid_for_product) {
                 $apply_recurring_coupon = $apply_recurring_percent_coupon = $apply_initial_coupon = $apply_initial_percent_coupon = false;
                 // Apply recurring fee discounts to recurring total calculations
                 if ('recurring_total' == $calculation_type) {
                     $apply_recurring_coupon = 'recurring_fee' == $coupon->type ? true : false;
                     $apply_recurring_percent_coupon = 'recurring_percent' == $coupon->type ? true : false;
                 }
                 if ('none' == $calculation_type) {
                     // If all items have a free trial we don't need to apply recurring coupons to the initial total
                     if (!WC_Subscriptions_Cart::all_cart_items_have_free_trial()) {
                         if ('recurring_fee' == $coupon->type) {
                             $apply_initial_coupon = true;
                         }
                         if ('recurring_percent' == $coupon->type) {
                             $apply_initial_percent_coupon = true;
                         }
                     }
                     // Apply sign-up discounts to initial total
                     if (!empty($cart_item['data']->subscription_sign_up_fee)) {
                         if ('sign_up_fee' == $coupon->type) {
                             $apply_initial_coupon = true;
                         }
                         if ('sign_up_fee_percent' == $coupon->type) {
                             $apply_initial_percent_coupon = true;
                         }
                         $calculation_price = $cart_item['data']->subscription_sign_up_fee;
                     }
                 }
                 if ($apply_recurring_coupon || $apply_initial_coupon) {
                     $discount_amount = $calculation_price < $coupon->amount ? $calculation_price : $coupon->amount;
                     // Recurring coupons only apply when there is no free trial (carts can have a mix of free trial and non free trial items)
                     if ($apply_initial_coupon && 'recurring_fee' == $coupon->type && !empty($cart_item['data']->subscription_trial_length)) {
                         $discount_amount = 0;
                     }
                     $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity'];
                     $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']);
                     $price = $price - $discount_amount;
                 } elseif ($apply_recurring_percent_coupon) {
                     $discount_amount = round($calculation_price / 100 * $coupon->amount, WC()->cart->dp);
                     $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity'];
                     $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']);
                     $price = $price - $discount_amount;
                 } elseif ($apply_initial_percent_coupon) {
                     // Recurring coupons only apply when there is no free trial (carts can have a mix of free trial and non free trial items)
                     if ('recurring_percent' == $coupon->type && empty($cart_item['data']->subscription_trial_length)) {
                         $amount_to_discount = $cart_item['data']->subscription_price;
                     } else {
                         $amount_to_discount = 0;
                     }
                     // Sign up fee coupons only apply to sign up fees
                     if ('sign_up_fee_percent' == $coupon->type) {
                         $amount_to_discount = $cart_item['data']->subscription_sign_up_fee;
                     }
                     $discount_amount = round($amount_to_discount / 100 * $coupon->amount, WC()->cart->dp);
                     $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity'];
                     $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']);
                     $price = $price - $discount_amount;
                 }
             }
         }
         if ($price < 0) {
             $price = 0;
         }
     }
     return $price;
 }
    /**
     * Display recurring order totals on the "Edit Order" page.
     *
     * @param int $post_id The post ID of the shop_order post object.
     * @since 1.2.4
     * @return void
     */
    public static function recurring_order_totals_meta_box_section($post_id)
    {
        global $woocommerce, $wpdb, $current_screen;
        $order = new WC_Order($post_id);
        $display_none = ' style="display: none"';
        $contains_subscription = self::order_contains_subscription($order) ? true : false;
        $chosen_gateway = WC_Subscriptions_Payment_Gateways::get_payment_gateway(get_post_meta($post_id, '_recurring_payment_method', true));
        $manual_renewal = self::requires_manual_renewal($post_id);
        $changes_supported = $chosen_gateway === false || $manual_renewal == 'true' || $chosen_gateway->supports('subscription_amount_changes') ? 'true' : 'false';
        $data = get_post_meta($post_id);
        if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
            ?>
	<div class="clear"></div>
</div>
		<?php 
        }
        ?>
<div id="gateway_support"<?php 
        if (!$contains_subscription) {
            echo $display_none;
        }
        ?>
>
	<input type="hidden" name="gateway_supports_subscription_changes" value="<?php 
        echo $changes_supported;
        ?>
">
	<div class="error"<?php 
        if (!$contains_subscription || $changes_supported == 'true') {
            echo $display_none;
        }
        ?>
>
		<p><?php 
        printf(__('The %s payment gateway is used to charge automatic subscription payments for this order. This gateway <strong>does not</strong> support changing a subscription\'s details.', 'woocommerce-subscriptions'), get_post_meta($post_id, '_recurring_payment_method_title', true));
        ?>
</p>
		<p>
			<?php 
        _e('It is strongly recommended you <strong>do not change</strong> any of the recurring totals or subscription item\'s details.', 'woocommerce-subscriptions');
        ?>
			<a href="http://docs.woothemes.com/document/subscriptions/add-or-modify-a-subscription/#section-4"><?php 
        _e('Learn More', 'woocommerce-subscriptions');
        ?>
 &raquo;</a>
		</p>
	</div>
</div>
<div id="recurring_order_totals"<?php 
        if (!$contains_subscription) {
            echo $display_none;
        }
        ?>
>
	<?php 
        if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
            ?>
	<h3><?php 
            _e('Recurring Totals', 'woocommerce-subscriptions');
            ?>
</h3>
	<?php 
        }
        ?>

	<?php 
        if ('add' !== $current_screen->action) {
            // Can't add recurring shipping to a manually added subscription
            ?>
	<div class="totals_group">
		<h4><span class="tax_total_display inline_total"></span><?php 
            _e('Shipping for Renewal Orders', 'woocommerce-subscriptions');
            ?>
</h4>
		<div id="recurring_shipping_rows">
		<?php 
            if (!WC_Subscriptions::is_woocommerce_pre('2.1')) {
                if ($woocommerce->shipping()) {
                    $shipping_methods = $woocommerce->shipping->load_shipping_methods();
                }
                foreach (self::get_recurring_shipping_methods($order) as $item_id => $item) {
                    $chosen_method = $item['method_id'];
                    $shipping_title = $item['name'];
                    $shipping_cost = $item['cost'];
                    include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/post-types/writepanels/order-shipping-html.php';
                }
                // Shipping created pre 2.1
                if (isset($data['_recurring_shipping_method'])) {
                    $item_id = 'old';
                    // so that when saving, we know to delete the data in the old form
                    $chosen_method = !empty($data['_recurring_shipping_method'][0]) ? $data['_recurring_shipping_method'][0] : '';
                    $shipping_title = !empty($data['_recurring_shipping_method_title'][0]) ? $data['_recurring_shipping_method_title'][0] : '';
                    $shipping_cost = !empty($data['_order_recurring_shipping_total'][0]) ? $data['_order_recurring_shipping_total'][0] : '0.00';
                    include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/post-types/writepanels/order-shipping-html.php';
                }
                ?>
		<?php 
            } else {
                // WC < 2.1
                ?>
			<ul class="totals">
				<li class="wide">
					<label><?php 
                _e('Label:', 'woocommerce-subscriptions');
                ?>
</label>
					<input type="text" id="_recurring_shipping_method_title" name="_recurring_shipping_method_title" placeholder="<?php 
                _e('The shipping title for renewal orders', 'woocommerce-subscriptions');
                ?>
" value="<?php 
                echo $order->recurring_shipping_method_title;
                ?>
" class="first" />
				</li>

				<li class="left">
					<label><?php 
                _e('Cost:', 'woocommerce-subscriptions');
                ?>
</label>
					<input type="text" id="_order_recurring_shipping_total" name="_order_recurring_shipping_total" placeholder="0.00 <?php 
                _e('(ex. tax)', 'woocommerce-subscriptions');
                ?>
" value="<?php 
                echo self::get_recurring_shipping_total($order);
                ?>
" class="first" />
				</li>

				<li class="right">
					<label><?php 
                _e('Method:', 'woocommerce-subscriptions');
                ?>
</label>
					<select name="_recurring_shipping_method" id="_recurring_shipping_method" class="first">
						<option value=""><?php 
                _e('N/A', 'woocommerce-subscriptions');
                ?>
</option>
						<?php 
                $chosen_shipping_method = $order->recurring_shipping_method;
                $found_method = false;
                if ($woocommerce->shipping()) {
                    foreach ($woocommerce->shipping->load_shipping_methods() as $method) {
                        if (strpos($chosen_shipping_method, $method->id) === 0) {
                            $value = $chosen_shipping_method;
                        } else {
                            $value = $method->id;
                        }
                        echo '<option value="' . esc_attr($value) . '" ' . selected($chosen_shipping_method == $value, true, false) . '>' . esc_html($method->get_title()) . '</option>';
                        if ($chosen_shipping_method == $value) {
                            $found_method = true;
                        }
                    }
                }
                if (!$found_method && !empty($chosen_shipping_method)) {
                    echo '<option value="' . esc_attr($chosen_shipping_method) . '" selected="selected">' . __('Other', 'woocommerce-subscriptions') . '</option>';
                } else {
                    echo '<option value="other">' . __('Other', 'woocommerce-subscriptions') . '</option>';
                }
                ?>
					</select>
				</li>
			</ul>
		<?php 
            }
            // ! WC_Subscriptions::is_woocommerce_pre( '2.1' )
            ?>
		</div>
		<div class="clear"></div>
	</div>
	<?php 
        }
        ?>

	<?php 
        if ('yes' == get_option('woocommerce_calc_taxes')) {
            ?>

	<div class="totals_group tax_rows_group">
		<h4>
			<span class="tax_total_display inline_total"></span>
			<?php 
            _e('Recurring Taxes', 'woocommerce-subscriptions');
            ?>
			<a class="tips" data-tip="<?php 
            _e('These rows contain taxes included in each recurring amount for this subscription. This allows you to display multiple or compound taxes rather than a single total on future subscription renewal orders.', 'woocommerce-subscriptions');
            ?>
" href="#">[?]</a>
		</h4>
		<div id="recurring_tax_rows" class="total_rows">
			<?php 
            $loop = 0;
            $taxes = self::get_recurring_taxes($order);
            if (is_array($taxes) && sizeof($taxes) > 0) {
                $rates = $wpdb->get_results("SELECT tax_rate_id, tax_rate_country, tax_rate_state, tax_rate_name, tax_rate_priority FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name");
                $tax_codes = array();
                foreach ($rates as $rate) {
                    $code = array();
                    $code[] = $rate->tax_rate_country;
                    $code[] = $rate->tax_rate_state;
                    $code[] = $rate->tax_rate_name ? sanitize_title($rate->tax_rate_name) : 'TAX';
                    $code[] = absint($rate->tax_rate_priority);
                    $tax_codes[$rate->tax_rate_id] = strtoupper(implode('-', array_filter($code)));
                }
                foreach ($taxes as $item_id => $item) {
                    include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/post-types/writepanels/order-tax-html.php';
                    $loop++;
                }
            }
            ?>
		</div>
		<h4 style="padding-bottom: 10px;"><a href="#" class="add_recurring_tax_row"><?php 
            _e('+ Add tax row', 'woocommerce-subscriptions');
            ?>
</a></h4>
		<div class="clear"></div>
	</div>

	<?php 
            if (WC_Subscriptions::is_woocommerce_pre('2.1')) {
                ?>
	<div class="totals_group">
		<h4><span class="tax_total_display inline_total"></span><?php 
                _e('Tax Totals', 'woocommerce-subscriptions');
                ?>
</h4>
		<ul class="totals">

			<li class="left">
				<label><?php 
                _e('Recurring Sales Tax:', 'woocommerce-subscriptions');
                ?>
</label>
				<input type="number" step="any" min="0" id="_order_recurring_tax_total" name="_order_recurring_tax_total" placeholder="0.00" value="<?php 
                echo self::get_recurring_total_tax($order);
                ?>
" class="calculated" />
			</li>

			<li class="right">
				<label><?php 
                _e('Shipping Tax:', 'woocommerce-subscriptions');
                ?>
</label>
				<input type="number" step="any" min="0" id="_order_recurring_shipping_tax_total" name="_order_recurring_shipping_tax_total" placeholder="0.00" value="<?php 
                echo self::get_recurring_shipping_tax_total($order);
                ?>
" class="calculated" />
			</li>

		</ul>
		<div class="clear"></div>
	</div>
	<?php 
            }
            // WC_Subscriptions::is_woocommerce_pre( '2.1' )
            ?>

	<?php 
        }
        // woocommerce_calc_taxes
        ?>

	<div class="totals_group">
		<h4><label for="_order_recurring_discount_total"><?php 
        _e('Recurring Order Discount', 'woocommerce-subscriptions');
        ?>
 <a class="tips" data-tip="<?php 
        _e('The discounts applied to each recurring payment charged in the future.', 'woocommerce-subscriptions');
        ?>
" href="#">[?]</a></label></h4>
		<input type="text" class="wc_input_price"  id="_order_recurring_discount_total" name="_order_recurring_discount_total" placeholder="<?php 
        echo wc_format_localized_price(0);
        ?>
" value="<?php 
        echo esc_attr(wc_format_localized_price(self::get_recurring_discount_total($order)));
        ?>
" style="margin: 6px 0 10px;"/>
	</div>

	<div class="totals_group">
		<h4><label for="_order_recurring_total"><?php 
        _e('Recurring Order Total', 'woocommerce-subscriptions');
        ?>
 <a class="tips" data-tip="<?php 
        _e('The total amounts charged for each future recurring payment.', 'woocommerce-subscriptions');
        ?>
" href="#">[?]</a></label></h4>
		<input type="text" id="_order_recurring_total" name="_order_recurring_total" placeholder="<?php 
        echo wc_format_localized_price(0);
        ?>
" value="<?php 
        echo esc_attr(wc_format_localized_price(self::get_recurring_total($order)));
        ?>
" class="calculated"  style="margin: 6px 0 10px;"/>
	</div>

	<div class="totals_group">
		<h4><?php 
        _e('Recurring Payment Method:', 'woocommerce-subscriptions');
        ?>
</h4>
		<div class="<?php 
        echo $order->recurring_payment_method;
        ?>
" style="padding-top: 4px; font-style: italic; margin: 2px 0 10px;"><?php 
        echo $manual_renewal || empty($order->recurring_payment_method) ? __('Manual', 'woocommerce-subscriptions') : $order->recurring_payment_method_title;
        ?>
</div>
	</div>
		<?php 
        if (!WC_Subscriptions::is_woocommerce_pre('2.2')) {
            ?>
</div>
		<?php 
        }
    }
 /**
  * A WooCommerce version aware function for getting the Subscriptions admin settings
  * tab URL.
  *
  * @since 1.4.5
  * @return string
  */
 public static function settings_tab_url()
 {
     if (WC_Subscriptions::is_woocommerce_pre('2.1')) {
         $settings_tab_url = admin_url('admin.php?page=woocommerce_settings&tab=subscriptions');
     } else {
         $settings_tab_url = admin_url('admin.php?page=wc-settings&tab=subscriptions');
     }
     return apply_filters('woocommerce_subscriptions_settings_tab_url', $settings_tab_url);
 }
 /**
  * Adds all necessary admin styles.
  *
  * @param array Array of Product types & their labels, excluding the Subscription product type.
  * @return array Array of Product types & their labels, including the Subscription product type.
  * @since 1.0
  */
 public static function enqueue_styles_scripts()
 {
     global $post;
     // Get admin screen id
     $screen = get_current_screen();
     $is_woocommerce_screen = in_array($screen->id, array('product', 'edit-shop_order', 'shop_order', 'edit-shop_subscription', 'shop_subscription', 'users', 'woocommerce_page_wc-settings')) ? true : false;
     $is_activation_screen = get_transient(WC_Subscriptions::$activation_transient) == true ? true : false;
     if ($is_woocommerce_screen) {
         $dependencies = array('jquery');
         $woocommerce_admin_script_handle = 'wc-admin-meta-boxes';
         if ($screen->id == 'product') {
             $dependencies[] = $woocommerce_admin_script_handle;
             $dependencies[] = 'wc-admin-product-meta-boxes';
             $dependencies[] = 'wc-admin-variation-meta-boxes';
             $script_params = array('productType' => WC_Subscriptions::$name, 'trialPeriodSingular' => wcs_get_available_time_periods(), 'trialPeriodPlurals' => wcs_get_available_time_periods('plural'), 'subscriptionLengths' => wcs_get_subscription_ranges(), 'trialTooLongMessages' => self::get_trial_period_validation_message('separate'), 'bulkEditPeriodMessage' => __('Enter the new period, either day, week, month or year:', 'woocommerce-subscriptions'), 'bulkEditLengthMessage' => __('Enter a new length (e.g. 5):', 'woocommerce-subscriptions'), 'bulkEditIntervalhMessage' => __('Enter a new interval as a single number (e.g. to charge every 2nd month, enter 2):', 'woocommerce-subscriptions'));
         } else {
             if ('edit-shop_order' == $screen->id) {
                 $script_params = array('bulkTrashWarning' => __("You are about to trash one or more orders which contain a subscription.\n\nTrashing the orders will also trash the subscriptions purchased with these orders.", 'woocommerce-subscriptions'));
             } else {
                 if ('shop_order' == $screen->id) {
                     $dependencies[] = $woocommerce_admin_script_handle;
                     $dependencies[] = 'wc-admin-order-meta-boxes';
                     $dependencies[] = 'wc-admin-order-meta-boxes-modal';
                     $script_params = array('bulkTrashWarning' => __('Trashing this order will also trash the subscription purchased with the order.', 'woocommerce-subscriptions'), 'changeMetaWarning' => __("WARNING: Bad things are about to happen!\n\nThe payment gateway used to purchase this subscription does not support modifying a subscription's details.\n\nChanges to the billing period, recurring discount, recurring tax or recurring total may not be reflected in the amount charged by the payment gateway.", 'woocommerce-subscriptions'), 'removeItemWarning' => __('You are deleting a subscription item. You will also need to manually cancel and trash the subscription on the Manage Subscriptions screen.', 'woocommerce-subscriptions'), 'roundAtSubtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'EditOrderNonce' => wp_create_nonce('woocommerce-subscriptions'), 'postId' => $post->ID);
                 } else {
                     if ('users' == $screen->id) {
                         $script_params = array('deleteUserWarning' => __("Warning: Deleting a user will also delete the user's subscriptions. The user's orders will remain but be reassigned to the 'Guest' user.\n\nDo you want to continue to delete this user and any associated subscriptions?", 'woocommerce-subscriptions'));
                     }
                 }
             }
         }
         $script_params['ajaxLoaderImage'] = WC()->plugin_url() . '/assets/images/ajax-loader.gif';
         $script_params['ajaxUrl'] = admin_url('admin-ajax.php');
         $script_params['isWCPre23'] = var_export(WC_Subscriptions::is_woocommerce_pre('2.3'), true);
         $script_params['isWCPre24'] = var_export(WC_Subscriptions::is_woocommerce_pre('2.4'), true);
         wp_enqueue_script('woocommerce_subscriptions_admin', plugin_dir_url(WC_Subscriptions::$plugin_file) . 'assets/js/admin/admin.js', $dependencies, filemtime(plugin_dir_path(WC_Subscriptions::$plugin_file) . 'assets/js/admin/admin.js'));
         wp_localize_script('woocommerce_subscriptions_admin', 'WCSubscriptions', apply_filters('woocommerce_subscriptions_admin_script_parameters', $script_params));
         // Maybe add the pointers for first timers
         if (isset($_GET['subscription_pointers']) && self::show_user_pointers()) {
             $dependencies[] = 'wp-pointer';
             $pointer_script_params = array('typePointerContent' => sprintf(_x('%1$sChoose Subscription%2$s%3$sThe WooCommerce Subscriptions extension adds two new subscription product types - %4$sSimple subscription%5$s and %6$sVariable subscription%7$s.%8$s', 'used in admin pointer script params in javascript as type pointer content', 'woocommerce-subscriptions'), '<h3>', '</h3>', '<p>', '<em>', '</em>', '<em>', '</em>', '</p>'), 'pricePointerContent' => sprintf(_x('%1$sSet a Price%2$s%3$sSubscription prices are a little different to other product prices. For a subscription, you can set a billing period, length, sign-up fee and free trial.%4$s', 'used in admin pointer script params in javascript as price pointer content', 'woocommerce-subscriptions'), '<h3>', '</h3>', '<p>', '</p>'));
             wp_enqueue_script('woocommerce_subscriptions_admin_pointers', plugin_dir_url(WC_Subscriptions::$plugin_file) . 'assets/js/admin/admin-pointers.js', $dependencies, WC_Subscriptions::$version);
             wp_localize_script('woocommerce_subscriptions_admin_pointers', 'WCSPointers', apply_filters('woocommerce_subscriptions_admin_pointer_script_parameters', $pointer_script_params));
             wp_enqueue_style('wp-pointer');
         }
     }
     // Maybe add the admin notice
     if ($is_activation_screen) {
         $woocommerce_plugin_dir_file = self::get_woocommerce_plugin_dir_file();
         if (!empty($woocommerce_plugin_dir_file)) {
             wp_enqueue_style('woocommerce-activation', plugins_url('/assets/css/activation.css', self::get_woocommerce_plugin_dir_file()), array(), WC_Subscriptions::$version);
             if (!isset($_GET['page']) || 'wcs-about' != $_GET['page']) {
                 add_action('admin_notices', __CLASS__ . '::admin_installed_notice');
             }
         }
         delete_transient(WC_Subscriptions::$activation_transient);
     }
     if ($is_woocommerce_screen || $is_activation_screen) {
         wp_enqueue_style('woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_Subscriptions::$version);
         wp_enqueue_style('woocommerce_subscriptions_admin', plugin_dir_url(WC_Subscriptions::$plugin_file) . 'assets/css/admin.css', array('woocommerce_admin_styles'), WC_Subscriptions::$version);
     }
 }
}
?>
<tr class="shipping recurring-total <?php 
echo esc_attr($recurring_cart_key);
?>
">
	<th><?php 
echo wp_kses_post($package_name);
?>
</th>
	<td data-title="<?php 
echo esc_attr($package_name);
?>
">
		<?php 
if (WC_Subscriptions::is_woocommerce_pre('2.6') && is_cart()) {
    // WC < 2.6 did not allow string indexes for shipping methods on the cart page and there was no way to hook in
    ?>
			<?php 
    echo wp_kses_post(wpautop(__('Recurring shipping options can be selected on checkout.', 'woocommerce-subscriptions')));
    ?>
		<?php 
} elseif (1 < count($available_methods)) {
    ?>
			<ul id="shipping_method_<?php 
    echo esc_attr($recurring_cart_key);
    ?>
">
				<?php 
    foreach ($available_methods as $method) {
        ?>
/**
 * Get an instance of WC_Order_Item_Meta for an order item
 *
 * @param array
 * @return WC_Order_Item_Meta
 * @since 2.0
 */
function wcs_get_order_item_meta($item, $product = null)
{
    if (WC_Subscriptions::is_woocommerce_pre('2.4')) {
        $item_meta = new WC_Order_Item_Meta($item['item_meta'], $product);
    } else {
        $item_meta = new WC_Order_Item_Meta($item, $product);
    }
    return $item_meta;
}
 /**
  * Handles partial refunds on orders in WC versions pre 2.5 which would be considered full refunds in WC 2.5.
  *
  * @param $order_id
  *
  * @since 2.0
  */
 public static function maybe_cancel_subscription_on_partial_refund($order_id)
 {
     if (WC_Subscriptions::is_woocommerce_pre('2.5') && wcs_order_contains_subscription($order_id, array('parent', 'renewal'))) {
         $order = wc_get_order($order_id);
         $remaining_order_total = wc_format_decimal($order->get_total() - $order->get_total_refunded());
         $remaining_order_items = absint($order->get_item_count() - $order->get_item_count_refunded());
         $order_has_free_item = false;
         foreach ($order->get_items() as $item) {
             if (!$item['line_total']) {
                 $order_has_free_item = true;
                 break;
             }
         }
         if (!($remaining_order_total > 0 || $order_has_free_item && $remaining_order_items > 0)) {
             self::maybe_cancel_subscription_on_full_refund($order);
         }
     }
 }
        ?>
						<?php 
        echo WC_Subscriptions_Order::get_item_name($subscription_details['order_id'], $subscription_details['product_id']);
        ?>
					<?php 
        if (false !== $product) {
            ?>
					</a>
					<?php 
        }
        ?>
					<?php 
        $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $subscription_details['product_id']);
        ?>
					<?php 
        if (WC_Subscriptions::is_woocommerce_pre('2.4')) {
            ?>
						<?php 
            $item_meta = new WC_Order_Item_Meta($order_item['item_meta'], $product);
            ?>
					<?php 
        } else {
            ?>
						<?php 
            $item_meta = new WC_Order_Item_Meta($order_item, $product);
            ?>
					<?php 
        }
        ?>
					<?php 
        $meta_to_display = $item_meta->display(true, true);
 /**
  * Creates a new order for renewing a subscription product based on the details of a previous order.
  *
  * No trial periods or sign up fees are applied to the renewal order. However, if the order has failed
  * payments and the store manager has set failed payments to be added to renewal orders, then the
  * orders totals will be set to include the outstanding balance.
  *
  * If the $args['new_order_role'] flag is set to 'parent', then the renewal order will supersede the existing
  * order. The existing order and subscription associated with it will be cancelled. A new order and
  * subscription will be created.
  *
  * If the $args['new_order_role'] flag is 'child', the $original_order will remain the master order for the
  * subscription and the new order is just for accepting a recurring payment on the subscription.
  *
  * Renewal orders have the same meta data as the original order. If the renewal order is set to be a 'child'
  * then any subscription related meta data will not be stored on the new order. This is to keep subscription
  * meta data associated only with the one master order for the subscription.
  *
  * @param WC_Order|int $order The WC_Order object or ID of the order for which the a new order should be created.
  * @param string $product_id The ID of the subscription product in the order which needs to be added to the new order.
  * @param array $args (optional) An array of name => value flags:
  *         'new_order_role' string A flag to indicate whether the new order should become the master order for the subscription. Accepts either 'parent' or 'child'. Defaults to 'parent' - replace the existing order.
  *         'checkout_renewal' bool Indicates if invoked from an interactive cart/checkout session and certain order items are not set, like taxes, shipping as they need to be set in teh calling function, like @see WC_Subscriptions_Checkout::filter_woocommerce_create_order(). Default false.
  *         'failed_order_id' int For checkout_renewal true, indicates order id being replaced
  * @since 1.2
  */
 public static function generate_renewal_order($original_order, $product_id, $args = array())
 {
     global $wpdb, $woocommerce;
     if (!is_object($original_order)) {
         $original_order = new WC_Order($original_order);
     }
     if (!WC_Subscriptions_Order::order_contains_subscription($original_order) || !WC_Subscriptions_Order::is_item_subscription($original_order, $product_id)) {
         return false;
     }
     if (self::is_renewal($original_order, array('order_role' => 'child'))) {
         $original_order = self::get_parent_order($original_order);
     }
     if (!is_array($args)) {
         _deprecated_argument(__CLASS__ . '::' . __FUNCTION__, '1.3', __('Third parameter is now an array of name => value pairs. Use array( "new_order_role" => "parent" ) instead.', 'woocommerce-subscriptions'));
         $args = array('new_order_role' => $args);
     }
     $args = wp_parse_args($args, array('new_order_role' => 'parent', 'checkout_renewal' => false));
     $renewal_order_key = uniqid('order_');
     // Create the new order
     $renewal_order_data = array('post_type' => 'shop_order', 'post_title' => sprintf(__('Subscription Renewal Order &ndash; %s', 'woocommerce-subscriptions'), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce-subscriptions'))), 'ping_status' => 'closed', 'post_excerpt' => $original_order->customer_note, 'post_author' => 1, 'post_password' => $renewal_order_key);
     $create_new_order = true;
     if (!WC_Subscriptions::is_woocommerce_pre('2.2')) {
         // WC 2.2 order status
         $renewal_order_data['post_status'] = 'wc-pending';
     } else {
         $renewal_order_data['post_status'] = 'publish';
     }
     if ('child' == $args['new_order_role']) {
         $renewal_order_data['post_parent'] = $original_order->id;
     }
     if (true === $args['checkout_renewal']) {
         $renewal_order_id = null;
         if ($woocommerce->session->order_awaiting_payment > 0) {
             $renewal_order_id = absint($woocommerce->session->order_awaiting_payment);
         } elseif (isset($args['failed_order_id'])) {
             $failed_order_id = $args['failed_order_id'];
             if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
                 // WC 2.1  - need to use taxonomy
                 /* Check order is unpaid by getting its status */
                 $terms = wp_get_object_terms($failed_order_id, 'shop_order_status', array('fields' => 'slugs'));
                 $order_status = isset($terms[0]) ? $terms[0] : 'pending';
             } else {
                 // WC 2.2+
                 $failed_order = wc_get_order($failed_order_id);
                 $order_status = $failed_order->get_status();
             }
             /* If paying on a pending order, we are resuming */
             if ($order_status == 'pending') {
                 $renewal_order_id = $failed_order_id;
             }
         }
         if ($renewal_order_id) {
             if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
                 // WC 2.1  - need to use taxonomy
                 /* Check order is unpaid by getting its status */
                 $terms = wp_get_object_terms($renewal_order_id, 'shop_order_status', array('fields' => 'slugs'));
                 $order_status = isset($terms[0]) ? $terms[0] : 'pending';
             } else {
                 // WC 2.2+
                 $existing_order = wc_get_order($renewal_order_id);
                 $order_status = $existing_order->get_status();
             }
             // Resume the unpaid order if its pending
             if ($order_status == 'pending' || $order_status == 'failed') {
                 // Update the existing order as we are resuming it
                 $create_new_order = false;
                 $renewal_order_data['ID'] = $renewal_order_id;
                 wp_update_post($renewal_order_data);
                 // Clear the old line items - we'll add these again in case they changed
                 $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d )", $renewal_order_id));
                 $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $renewal_order_id));
             }
         }
     }
     if ($create_new_order) {
         $renewal_order_id = wp_insert_post($renewal_order_data);
     }
     if (WC_Subscriptions::is_woocommerce_pre('2.2')) {
         // WC 2.1 order status
         // Set the order as pending
         wp_set_object_terms($renewal_order_id, 'pending', 'shop_order_status');
     }
     // Set a unique key for this order
     update_post_meta($renewal_order_id, '_order_key', $renewal_order_key);
     $order_meta_query = "SELECT `meta_key`, `meta_value`\n\t\t\t\t\t\t\t FROM {$wpdb->postmeta}\n\t\t\t\t\t\t\t WHERE `post_id` = {$original_order->id}\n\t\t\t\t\t\t\t AND `meta_key` NOT IN ('_paid_date', '_completed_date', '_order_key', '_edit_lock', '_original_order', '_wc_points_earned', '_transaction_id')";
     // Superseding existing order so don't carry over payment details
     if ('parent' == $args['new_order_role'] || true === $args['checkout_renewal']) {
         $order_meta_query .= " AND `meta_key` NOT IN ('_payment_method', '_payment_method_title', '_recurring_payment_method', '_recurring_payment_method_title', '_shipping_method', '_shipping_method_title', '_recurring_shipping_method', '_recurring_shipping_method_title')";
     } else {
         $order_meta_query .= " AND `meta_key` NOT LIKE '_order_recurring_%' AND `meta_key` NOT IN ('_payment_method', '_payment_method_title', '_recurring_payment_method', '_recurring_payment_method_title', '_shipping_method', '_shipping_method_title', '_recurring_shipping_method', '_recurring_shipping_method_title')";
     }
     // Allow extensions to add/remove order meta
     $order_meta_query = apply_filters('woocommerce_subscriptions_renewal_order_meta_query', $order_meta_query, $original_order->id, $renewal_order_id, $args['new_order_role']);
     // Carry all the required meta from the old order over to the new order
     $order_meta = $wpdb->get_results($order_meta_query, 'ARRAY_A');
     $order_meta = apply_filters('woocommerce_subscriptions_renewal_order_meta', $order_meta, $original_order->id, $renewal_order_id, $args['new_order_role']);
     foreach ($order_meta as $meta_item) {
         add_post_meta($renewal_order_id, $meta_item['meta_key'], maybe_unserialize($meta_item['meta_value']), true);
     }
     $outstanding_balance = WC_Subscriptions_Order::get_outstanding_balance($original_order, $product_id);
     $failed_payment_multiplier = 1;
     if (false == $args['checkout_renewal']) {
         // If there are outstanding payment amounts, add them to the order, otherwise set the order details to the values of the recurring totals
         if ($outstanding_balance > 0 && 'yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_add_outstanding_balance', 'no')) {
             $failed_payment_multiplier += WC_Subscriptions_Order::get_failed_payment_count($original_order, $product_id);
         }
         // Set order totals based on recurring totals from the original order
         $cart_discount = $failed_payment_multiplier * wc_format_decimal(get_post_meta($original_order->id, '_order_recurring_discount_cart', true));
         $order_discount = $failed_payment_multiplier * wc_format_decimal(get_post_meta($original_order->id, '_order_recurring_discount_total', true));
         $order_shipping_tax = $failed_payment_multiplier * wc_format_decimal(get_post_meta($original_order->id, '_order_recurring_shipping_tax_total', true));
         $order_shipping = $failed_payment_multiplier * wc_format_decimal(get_post_meta($original_order->id, '_order_recurring_shipping_total', true));
         $order_tax = $failed_payment_multiplier * wc_format_decimal(get_post_meta($original_order->id, '_order_recurring_tax_total', true));
         $order_total = $failed_payment_multiplier * wc_format_decimal(get_post_meta($original_order->id, '_order_recurring_total', true));
         update_post_meta($renewal_order_id, '_cart_discount', $cart_discount);
         update_post_meta($renewal_order_id, '_order_discount', $order_discount);
         update_post_meta($renewal_order_id, '_order_shipping_tax', $order_shipping_tax);
         update_post_meta($renewal_order_id, '_order_shipping', $order_shipping);
         update_post_meta($renewal_order_id, '_order_tax', $order_tax);
         update_post_meta($renewal_order_id, '_order_total', $order_total);
         // Set shipping for orders created with WC 2.0.n (or when we are using WC 2.0.n)
         if (WC_Subscriptions::is_woocommerce_pre('2.1') || isset($original_order->recurring_shipping_method)) {
             update_post_meta($renewal_order_id, '_shipping_method', $original_order->recurring_shipping_method);
             update_post_meta($renewal_order_id, '_shipping_method_title', $original_order->recurring_shipping_method_title);
             // Also set recurring shipping as it's a parent renewal order
             if ('parent' == $args['new_order_role']) {
                 update_post_meta($renewal_order_id, '_recurring_shipping_method', $original_order->recurring_shipping_method);
                 update_post_meta($renewal_order_id, '_recurring_shipping_method_title', $original_order->recurring_shipping_method_title);
             }
         }
         // Apply the recurring shipping & payment methods to child renewal orders
         if ('child' == $args['new_order_role']) {
             update_post_meta($renewal_order_id, '_payment_method', $original_order->recurring_payment_method);
             update_post_meta($renewal_order_id, '_payment_method_title', $original_order->recurring_payment_method_title);
         }
         // Set order taxes based on recurring taxes from the original order
         $recurring_order_taxes = WC_Subscriptions_Order::get_recurring_taxes($original_order);
         foreach ($recurring_order_taxes as $index => $recurring_order_tax) {
             $item_ids = array();
             $item_ids[] = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $recurring_order_tax['name'], 'order_item_type' => 'tax'));
             // Also set recurring taxes on parent renewal orders
             if ('parent' == $args['new_order_role']) {
                 $item_ids[] = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $recurring_order_tax['name'], 'order_item_type' => 'recurring_tax'));
             }
             // Add line item meta
             foreach ($item_ids as $item_id) {
                 woocommerce_add_order_item_meta($item_id, 'compound', absint(isset($recurring_order_tax['compound']) ? $recurring_order_tax['compound'] : 0));
                 woocommerce_add_order_item_meta($item_id, 'tax_amount', $failed_payment_multiplier * WC_Subscriptions::format_total($recurring_order_tax['tax_amount']));
                 woocommerce_add_order_item_meta($item_id, 'shipping_tax_amount', $failed_payment_multiplier * WC_Subscriptions::format_total($recurring_order_tax['shipping_tax_amount']));
                 if (isset($recurring_order_tax['rate_id'])) {
                     woocommerce_add_order_item_meta($item_id, 'rate_id', $recurring_order_tax['rate_id']);
                 }
                 if (isset($recurring_order_tax['label'])) {
                     woocommerce_add_order_item_meta($item_id, 'label', $recurring_order_tax['label']);
                 }
             }
         }
         // Set up shipping items on renewal order
         $recurring_shipping_items = WC_Subscriptions_Order::get_recurring_shipping_methods($original_order);
         foreach ($recurring_shipping_items as $recurring_shipping_item_id => $recurring_shipping_item) {
             $item_ids = array();
             $item_ids[] = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $recurring_shipping_item['name'], 'order_item_type' => 'shipping'));
             // Also set recurring shipping as it's a parent renewal order
             if ('parent' == $args['new_order_role']) {
                 $item_ids[] = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $recurring_shipping_item['name'], 'order_item_type' => 'recurring_shipping'));
             }
             // Add shipping item meta
             foreach ($item_ids as $item_id) {
                 woocommerce_add_order_item_meta($item_id, 'method_id', $recurring_shipping_item['method_id']);
                 woocommerce_add_order_item_meta($item_id, 'cost', $failed_payment_multiplier * WC_Subscriptions::format_total($recurring_shipping_item['cost']));
                 // Set line taxes for shipping
                 if (isset($recurring_shipping_item['taxes'])) {
                     $taxes = maybe_unserialize($recurring_shipping_item['taxes']);
                 } else {
                     // try to determine recurring shipping taxes from original order's shipping taxes
                     $taxes = array();
                     foreach ($original_order->get_shipping_methods() as $original_shipping_item_id => $original_shipping_item) {
                         // We need to use the amount of the same shipping method as this one
                         if ($recurring_shipping_item['method_id'] != $original_shipping_item['method_id']) {
                             continue;
                         }
                         // If we don't have taxes on the matching shipping item, there's nothing we can do
                         if (!isset($original_shipping_item['taxes'])) {
                             break;
                         }
                         $original_shipping_item['taxes'] = maybe_unserialize($original_shipping_item['taxes']);
                         // Make sure we account for any amount on the original original shipping not applied to renewals by determining what proportion of the initial amount the recurring total represents
                         if (0 != $original_shipping_item['cost'] && $recurring_shipping_item['cost'] != $original_shipping_item['cost']) {
                             $recurring_ratio = $recurring_shipping_item['cost'] / $original_shipping_item['cost'];
                             foreach ($original_shipping_item['taxes'] as $tax_id => $tax_amount) {
                                 $original_shipping_item['taxes'][$tax_id] = $recurring_ratio * $tax_amount;
                             }
                         }
                         foreach ($original_shipping_item['taxes'] as $tax_id => $tax_amount) {
                             $taxes[$tax_id] = WC_Subscriptions::format_total($failed_payment_multiplier * $tax_amount);
                         }
                     }
                 }
                 woocommerce_add_order_item_meta($item_id, 'taxes', $taxes);
             }
         }
     }
     // Set line totals to be recurring line totals and remove the subscription/recurring related item meta from each order item
     $order_items = WC_Subscriptions_Order::get_recurring_items($original_order);
     // Allow extensions to add/remove items or item meta
     $order_items = apply_filters('woocommerce_subscriptions_renewal_order_items', $order_items, $original_order->id, $renewal_order_id, $product_id, $args['new_order_role']);
     if (true === $args['checkout_renewal']) {
         $cart_items = $woocommerce->cart->get_cart();
     }
     foreach ($order_items as $item_index => $order_item) {
         $renewal_order_item_name = apply_filters('woocommerce_subscriptions_renewal_order_item_name', $order_item['name'], $order_item, $original_order);
         // Create order line item on the renewal order
         $recurring_item_id = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $renewal_order_item_name, 'order_item_type' => 'line_item'));
         if (true === $args['checkout_renewal']) {
             $cart_item = array();
             foreach ($cart_items as $item) {
                 if ($item['product_id'] == $order_item['product_id'] && (empty($order_item['variation_id']) || $item['variation_id'] == $order_item['variation_id'])) {
                     $cart_item = $item;
                 }
             }
             if (!empty($cart_item)) {
                 woocommerce_update_order_item_meta($recurring_item_id, '_line_total', woocommerce_format_decimal($cart_item['line_total']));
                 woocommerce_update_order_item_meta($recurring_item_id, '_line_tax', woocommerce_format_decimal($cart_item['line_tax']));
                 woocommerce_update_order_item_meta($recurring_item_id, '_line_subtotal', woocommerce_format_decimal($cart_item['line_subtotal']));
                 woocommerce_update_order_item_meta($recurring_item_id, '_line_subtotal_tax', woocommerce_format_decimal($cart_item['line_subtotal_tax']));
                 if (is_object($cart_item['data'])) {
                     woocommerce_update_order_item_meta($recurring_item_id, '_tax_class', $cart_item['data']->get_tax_class());
                 }
             }
             $cart_items = $woocommerce->cart->get_cart();
         }
         if (WC_Subscriptions::is_woocommerce_pre('2.4')) {
             $item_meta = new WC_Order_Item_Meta($order_item['item_meta']);
         } else {
             $item_meta = new WC_Order_Item_Meta($order_item);
         }
         // Remove recurring line items and set item totals based on recurring line totals
         foreach ($item_meta->meta as $meta_key => $meta) {
             // meta value might be an array. If it is, we need to preserve all values
             foreach ($meta as $key => $value) {
                 $meta_values[$key] = maybe_unserialize($value);
             }
             if (false === $args['checkout_renewal']) {
                 // Already set earlier
                 // Map line item totals based on recurring line totals
                 switch ($meta_key) {
                     case '_recurring_line_total':
                         woocommerce_update_order_item_meta($recurring_item_id, '_line_total', $failed_payment_multiplier * woocommerce_format_decimal($meta_values[0]));
                         break;
                     case '_recurring_line_tax':
                         woocommerce_update_order_item_meta($recurring_item_id, '_line_tax', $failed_payment_multiplier * woocommerce_format_decimal($meta_values[0]));
                         break;
                     case '_recurring_line_subtotal':
                         woocommerce_update_order_item_meta($recurring_item_id, '_line_subtotal', $failed_payment_multiplier * woocommerce_format_decimal($meta_values[0]));
                         break;
                     case '_recurring_line_subtotal_tax':
                         woocommerce_update_order_item_meta($recurring_item_id, '_line_subtotal_tax', $failed_payment_multiplier * woocommerce_format_decimal($meta_values[0]));
                         break;
                     case '_line_tax_data':
                         // Copy line tax data if the order doesn't have a _recurring_line_tax_data (for backward compatibility)
                         if (!array_key_exists('_recurring_line_tax_data', $item_meta->meta)) {
                             $meta_value = $meta_values[0];
                             $line_total = $item_meta->meta['_line_total'][0];
                             $recurring_line_total = $item_meta->meta['_recurring_line_total'][0];
                             // There will only be recurring tax data if the recurring amount is > 0 and we can only retroactively calculate recurring amount from initial amoutn if it is > 0
                             if ($line_total > 0 && $recurring_line_total > 0) {
                                 // Make sure we account for any sign-up fees by determining what proportion of the initial amount the recurring total represents
                                 $recurring_ratio = $recurring_line_total / $line_total;
                                 $recurring_tax_data = array();
                                 $tax_data_keys = array('total', 'subtotal');
                                 foreach ($tax_data_keys as $tax_data_key) {
                                     foreach ($meta_value[$tax_data_key] as $tax_index => $tax_value) {
                                         // Use total tax amount for both total and subtotal because we don't want any initial discounts to be applied to recurring amounts
                                         $total_tax_amount = $meta_value['total'][$tax_index];
                                         $recurring_tax_data[$tax_data_key][$tax_index] = woocommerce_format_decimal($failed_payment_multiplier * ($recurring_ratio * $total_tax_amount));
                                     }
                                 }
                             } else {
                                 $recurring_tax_data = array('total' => array(), 'subtotal' => array());
                             }
                             woocommerce_update_order_item_meta($recurring_item_id, '_line_tax_data', $recurring_tax_data);
                         }
                         break;
                     case '_recurring_line_tax_data':
                         $meta_value = $meta_values[0];
                         $recurring_tax_data = array();
                         $tax_data_keys = array('total', 'subtotal');
                         foreach ($tax_data_keys as $tax_data_key) {
                             foreach ($meta_value[$tax_data_key] as $tax_index => $tax_value) {
                                 $recurring_tax_data[$tax_data_key][$tax_index] = woocommerce_format_decimal($failed_payment_multiplier * $tax_value);
                             }
                         }
                         woocommerce_update_order_item_meta($recurring_item_id, '_line_tax_data', $recurring_tax_data);
                         break;
                     default:
                         break;
                 }
             }
             // Copy over line item meta data, with some parent/child role based exceptions for recurring amounts
             $copy_to_renewal_item = true;
             switch ($meta_key) {
                 case '_recurring_line_total':
                 case '_recurring_line_tax':
                 case '_recurring_line_subtotal':
                 case '_recurring_line_subtotal_tax':
                 case '_recurring_line_tax_data':
                 case '_line_tax_data':
                 case '_subscription_recurring_amount':
                 case '_subscription_sign_up_fee':
                 case '_subscription_period':
                 case '_subscription_interval':
                 case '_subscription_length':
                 case '_subscription_trial_period':
                 case '_subscription_end_date':
                 case '_subscription_expiry_date':
                 case '_subscription_start_date':
                 case '_subscription_status':
                 case '_subscription_completed_payments':
                     if ('child' == $args['new_order_role']) {
                         $copy_to_renewal_item = false;
                     }
                     break;
                 case '_subscription_trial_length':
                     // We never want to duplicate free trials on renewal orders
                     $copy_to_renewal_item = false;
                     break;
                 case '_subscription_suspension_count':
                     // We want to reset some values for the new order
                 // We want to reset some values for the new order
                 case '_subscription_trial_expiry_date':
                 case '_subscription_failed_payments':
                     $copy_to_renewal_item = false;
                     $meta_value = 0;
                     break;
                 default:
                     break;
             }
             // Copy existing item over to new recurring order item
             if ($copy_to_renewal_item) {
                 // cast it to an array. Arrays will be kept, strings will be an array. Tested back to PHP 5.2.16
                 foreach ($meta_values as $meta_value) {
                     woocommerce_add_order_item_meta($recurring_item_id, $meta_key, $meta_value);
                 }
             }
         }
     }
     if (false == $args['checkout_renewal']) {
         // Add fees
         foreach ($original_order->get_fees() as $item_id => $order_fee) {
             if (!isset($order_fee['recurring_line_total'])) {
                 continue;
             }
             $item_id = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $order_fee['name'], 'order_item_type' => 'fee'));
             woocommerce_add_order_item_meta($item_id, '_tax_class', $order_fee['tax_class']);
             woocommerce_add_order_item_meta($item_id, '_line_total', WC_Subscriptions::format_total($order_fee['recurring_line_total']));
             woocommerce_add_order_item_meta($item_id, '_line_tax', WC_Subscriptions::format_total($order_fee['recurring_line_tax']));
         }
     }
     // Keep a record of the original order's ID on the renewal order
     update_post_meta($renewal_order_id, '_original_order', $original_order->id, true);
     $renewal_order = new WC_Order($renewal_order_id);
     if ('parent' == $args['new_order_role']) {
         WC_Subscriptions_Manager::process_subscriptions_on_checkout($renewal_order_id);
         $original_order->add_order_note(sprintf(__('Order superseded by Renewal Order %s.', 'woocommerce-subscriptions'), $renewal_order->get_order_number()));
     }
     do_action('woocommerce_subscriptions_renewal_order_created', $renewal_order, $original_order, $product_id, $args['new_order_role']);
     return apply_filters('woocommerce_subscriptions_renewal_order_id', $renewal_order_id, $original_order, $product_id, $args['new_order_role']);
 }