예제 #1
0
 /**
  * Check whether the cart needs payment even if the order total is $0
  *
  * @param bool $needs_payment The existing flag for whether the cart needs payment or not.
  * @param WC_Cart $cart The WooCommerce cart object.
  * @return bool
  */
 public static function cart_needs_payment($needs_payment, $cart)
 {
     if (false === $needs_payment && self::cart_contains_subscription() && $cart->total == 0 && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
         $recurring_total = 0;
         $is_one_period = true;
         $is_synced = false;
         foreach (WC()->cart->recurring_carts as $cart) {
             $recurring_total += $cart->total;
             $cart_length = wcs_cart_pluck($cart, 'subscription_length');
             if (0 == $cart_length || wcs_cart_pluck($cart, 'subscription_period_interval') != $cart_length) {
                 $is_one_period = false;
             }
             $is_synced = $is_synced || false != WC_Subscriptions_Synchroniser::cart_contains_synced_subscription($cart) ? true : false;
         }
         $has_trial = self::cart_contains_free_trial();
         if ($recurring_total > 0 && (false === $is_one_period || true === $has_trial || false !== $is_synced && false == WC_Subscriptions_Synchroniser::is_today(WC_Subscriptions_Synchroniser::calculate_first_payment_date($is_synced['data'], 'timestamp')))) {
             $needs_payment = true;
         }
     }
     return $needs_payment;
 }
/**
 * Return a formatted price string for a given cart object
 *
 * @access public
 * @return void
 */
function wcs_cart_price_string($recurring_amount, $cart)
{
    return wcs_price_string(apply_filters('woocommerce_cart_subscription_string_details', array('recurring_amount' => $recurring_amount, 'subscription_interval' => wcs_cart_pluck($cart, 'subscription_period_interval'), 'subscription_period' => wcs_cart_pluck($cart, 'subscription_period', ''), 'subscription_length' => wcs_cart_pluck($cart, 'subscription_length'))));
}
 /**
  * Create a new subscription from a cart item on checkout.
  *
  * The function doesn't validate whether the cart item is a subscription product, meaning it can be used for any cart item,
  * but the item will need a `subscription_period` and `subscription_period_interval` value set on it, at a minimum.
  *
  * @param WC_Order $order
  * @param WC_Cart $cart
  * @since 2.0
  */
 public static function create_subscription($order, $cart)
 {
     global $wpdb;
     try {
         // Start transaction if available
         $wpdb->query('START TRANSACTION');
         // Set the recurring line totals on the subscription
         $variation_id = wcs_cart_pluck($cart, 'variation_id');
         $product_id = empty($variation_id) ? wcs_cart_pluck($cart, 'product_id') : $variation_id;
         // We need to use the $order->order_date value because the post_date_gmt isn't always set
         $order_date_gmt = get_gmt_from_date($order->order_date);
         $subscription = wcs_create_subscription(array('start_date' => $cart->start_date, 'order_id' => $order->id, 'customer_id' => $order->get_user_id(), 'billing_period' => wcs_cart_pluck($cart, 'subscription_period'), 'billing_interval' => wcs_cart_pluck($cart, 'subscription_period_interval'), 'customer_note' => $order->customer_note));
         if (is_wp_error($subscription)) {
             throw new Exception($subscription->get_error_message());
         }
         // Set the subscription's billing and shipping address
         $subscription = wcs_copy_order_address($order, $subscription);
         $subscription->update_dates(array('trial_end' => $cart->trial_end_date, 'next_payment' => $cart->next_payment_date, 'end' => $cart->end_date));
         // Store trial period for PayPal
         if (wcs_cart_pluck($cart, 'subscription_trial_length') > 0) {
             update_post_meta($subscription->id, '_trial_period', wcs_cart_pluck($cart, 'subscription_trial_period'));
         }
         // Set the payment method on the subscription
         $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
         if ($cart->needs_payment() && isset($available_gateways[$order->payment_method])) {
             $subscription->set_payment_method($available_gateways[$order->payment_method]);
         }
         if (!$cart->needs_payment() || 'yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) {
             $subscription->update_manual('true');
         } elseif (!isset($available_gateways[$order->payment_method]) || !$available_gateways[$order->payment_method]->supports('subscriptions')) {
             $subscription->update_manual('true');
         }
         wcs_copy_order_meta($order, $subscription, 'subscription');
         // Store the line items
         foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
             $item_id = self::add_cart_item($subscription, $cart_item, $cart_item_key);
         }
         // Store fees (although no fees recur by default, extensions may add them)
         foreach ($cart->get_fees() as $fee_key => $fee) {
             $item_id = $subscription->add_fee($fee);
             if (!$item_id) {
                 // translators: placeholder is an internal error number
                 throw new Exception(sprintf(__('Error %d: Unable to create subscription. Please try again.', 'woocommerce-subscriptions'), 403));
             }
             // Allow plugins to add order item meta to fees
             do_action('woocommerce_add_order_fee_meta', $order->id, $item_id, $fee, $fee_key);
         }
         self::add_shipping($subscription, $cart);
         // Store tax rows
         foreach (array_keys($cart->taxes + $cart->shipping_taxes) as $tax_rate_id) {
             if ($tax_rate_id && !$subscription->add_tax($tax_rate_id, $cart->get_tax_amount($tax_rate_id), $cart->get_shipping_tax_amount($tax_rate_id)) && apply_filters('woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated') !== $tax_rate_id) {
                 // translators: placeholder is an internal error number
                 throw new Exception(sprintf(__('Error %d: Unable to add tax to subscription. Please try again.', 'woocommerce-subscriptions'), 405));
             }
         }
         // Store coupons
         foreach ($cart->get_coupons() as $code => $coupon) {
             if (!$subscription->add_coupon($code, $cart->get_coupon_discount_amount($code), $cart->get_coupon_discount_tax_amount($code))) {
                 // translators: placeholder is an internal error number
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce-subscriptions'), 406));
             }
         }
         // Set the recurring totals on the subscription
         $subscription->set_total($cart->shipping_total, 'shipping');
         $subscription->set_total($cart->get_cart_discount_total(), 'cart_discount');
         $subscription->set_total($cart->get_cart_discount_tax_total(), 'cart_discount_tax');
         $subscription->set_total($cart->tax_total, 'tax');
         $subscription->set_total($cart->shipping_tax_total, 'shipping_tax');
         $subscription->set_total($cart->total);
         // If we got here, the subscription was created without problems
         $wpdb->query('COMMIT');
     } catch (Exception $e) {
         // There was an error adding the subscription
         $wpdb->query('ROLLBACK');
         return new WP_Error('checkout-error', $e->getMessage());
     }
     return $subscription;
 }