/** * Make sure the expiration date is calculated from the synced start date for products where the start date * will be synced. * * @param string $expiration_date MySQL formatted date on which the subscription is set to expire * @param mixed $product_id The product/post ID of the subscription * @param mixed $from_date A MySQL formatted date/time string from which to calculate the expiration date, or empty (default), which will use today's date/time. * @since 1.5 */ public static function recalculate_product_expiration_date($expiration_date, $product_id, $from_date) { if (self::is_product_synced($product_id) && ($subscription_length = WC_Subscriptions_Product::get_length($product_id)) > 0) { $subscription_period = WC_Subscriptions_Product::get_period($product_id); $first_payment_date = self::calculate_first_payment_date($product_id, 'timestamp'); $expiration_date = date('Y-m-d H:i:s', wcs_add_time($subscription_length, $subscription_period, $first_payment_date)); } return $expiration_date; }
/** * When a new order is inserted, add the subscriptions period to the order. * * It's important that the period is tied to the order so that changing the products * period does not change the past. * * @since 1.0 */ public static function add_order_meta($order_id) { global $woocommerce; if (WC_Subscriptions_Order::order_contains_subscription($order_id)) { $order = new WC_Order($order_id); $order_subscription_periods = array(); $order_subscription_intervals = array(); $order_subscription_lengths = array(); $order_subscription_trial_lengths = array(); foreach ($order->get_items() as $item) { $period = WC_Subscriptions_Product::get_period($item['id']); if (!empty($period)) { $order_subscription_periods[$item['id']] = $period; } $interval = WC_Subscriptions_Product::get_interval($item['id']); if (!empty($interval)) { $order_subscription_intervals[$item['id']] = $interval; } $length = WC_Subscriptions_Product::get_length($item['id']); if (!empty($length)) { $order_subscription_lengths[$item['id']] = $length; } $trial_length = WC_Subscriptions_Product::get_trial_length($item['id']); if (!empty($trial_length)) { $order_subscription_trial_lengths[$item['id']] = $trial_length; } } update_post_meta($order_id, '_order_subscription_periods', $order_subscription_periods); update_post_meta($order_id, '_order_subscription_intervals', $order_subscription_intervals); update_post_meta($order_id, '_order_subscription_lengths', $order_subscription_lengths); update_post_meta($order_id, '_order_subscription_trial_lengths', $order_subscription_trial_lengths); // Store sign-up fee details foreach (WC_Subscriptions_Cart::get_sign_up_fee_fields() as $field_name) { update_post_meta($order_id, "_{$field_name}", $woocommerce->cart->{$field_name}); } // Prepare sign up fee taxes to store in same format as order taxes $sign_up_fee_taxes = array(); foreach (array_keys($woocommerce->cart->sign_up_fee_taxes) as $key) { $is_compound = $woocommerce->cart->tax->is_compound($key) ? 1 : 0; $sign_up_fee_taxes[] = array('label' => $woocommerce->cart->tax->get_rate_label($key), 'compound' => $is_compound, 'cart_tax' => number_format($woocommerce->cart->sign_up_fee_taxes[$key], 2, '.', '')); } update_post_meta($order_id, '_sign_up_fee_taxes', $sign_up_fee_taxes); } }
/** * Gets the subscription period from the cart and returns it as an array (eg. array( 'month', 'day' ) ) * * @since 1.0 */ public static function get_cart_subscription_period() { global $woocommerce; foreach ($woocommerce->cart->cart_contents as $cart_item) { $item_id = empty($cart_item['variation_id']) ? $cart_item['product_id'] : $cart_item['variation_id']; if (isset($cart_item['data']->subscription_period)) { $period = $cart_item['data']->subscription_period; break; } elseif (WC_Subscriptions_Product::is_subscription($item_id)) { $period = WC_Subscriptions_Product::get_period($item_id); break; } } return apply_filters('woocommerce_subscriptions_cart_period', $period); }
/** * Calculate the first payment date for a synced subscription. * * The date is calculated in UTC timezone. * * @param WC_Product $product A subscription product. * @param string $type (optional) The format to return the first payment date in, either 'mysql' or 'timestamp'. Default 'mysql'. * @param string $from_date (optional) The date to calculate the first payment from in GMT/UTC timzeone. If not set, it will use the current date. This should not include any trial period on the product. * @since 1.5 */ public static function calculate_first_payment_date($product, $type = 'mysql', $from_date = '') { if (!is_object($product)) { $product = WC_Subscriptions::get_product($product); } if (!self::is_product_synced($product)) { return 0; } $period = WC_Subscriptions_Product::get_period($product); $trial_period = WC_Subscriptions_Product::get_trial_period($product); $trial_length = WC_Subscriptions_Product::get_trial_length($product); $from_date_param = $from_date; if (empty($from_date)) { $from_date = gmdate('Y-m-d H:i:s'); } // If the subscription has a free trial period, the first payment should be synced to a day after the free trial if ($trial_length > 0) { $from_date = WC_Subscriptions_Product::get_trial_expiration_date($product, $from_date); } $from_timestamp = strtotime($from_date) + get_option('gmt_offset') * 3600; // Site time $payment_day = self::get_products_payment_day($product); if ('week' == $period) { // strtotime() only handles English, so can't use $wp_locale->weekday here $weekdays = array(1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday'); // strtotime() will figure out if the day is in the future or today (see: https://gist.github.com/thenbrent/9698083) $first_payment_timestamp = strtotime($weekdays[$payment_day], $from_timestamp); } elseif ('month' == $period) { // strtotime() needs to know the month, so we need to determine if the specified day has occured this month yet or if we want the last day of the month (see: https://gist.github.com/thenbrent/9698083) if ($payment_day > 27) { // we actually want the last day of the month $payment_day = gmdate('t', $from_timestamp); $month = gmdate('F', $from_timestamp); } elseif (gmdate('j', $from_timestamp) > $payment_day) { // today is later than specified day in the from date, we need the next month $month = date('F', WC_Subscriptions::add_months($from_timestamp, 1)); } else { // specified day is either today or still to come in the month of the from date $month = gmdate('F', $from_timestamp); } $first_payment_timestamp = strtotime("{$payment_day} {$month}", $from_timestamp); } elseif ('year' == $period) { // We can't use $wp_locale here because it is translated switch ($payment_day['month']) { case 1: $month = 'January'; break; case 2: $month = 'February'; break; case 3: $month = 'March'; break; case 4: $month = 'April'; break; case 5: $month = 'May'; break; case 6: $month = 'June'; break; case 7: $month = 'July'; break; case 8: $month = 'August'; break; case 9: $month = 'September'; break; case 10: $month = 'October'; break; case 11: $month = 'November'; break; case 12: $month = 'December'; break; } $first_payment_timestamp = strtotime("{$payment_day['day']} {$month}", $from_timestamp); } // Make sure the next payment is in the future and after the $from_date, as strtotime() will return the date this year for any day in the past when adding months or years (see: https://gist.github.com/thenbrent/9698083) if ('year' == $period || 'month' == $period) { // First make sure the day is in the past so that we don't end up jumping a month or year because of a few hours difference between now and the billing date if (gmdate('j', $first_payment_timestamp) < gmdate('j') && gmdate('n', $first_payment_timestamp) <= gmdate('n') && gmdate('Y', $first_payment_timestamp) <= gmdate('Y')) { $i = 1; // Then make sure the date and time of the payment is in the future while (($first_payment_timestamp < gmdate('U') || $first_payment_timestamp < $from_timestamp) && $i < 30) { $first_payment_timestamp = strtotime("+ 1 {$period}", $first_payment_timestamp); $i = $i + 1; } } } // We calculated a timestamp for midnight on the specific day in the site's timezone, let's push it to 3am to account for any daylight savings changes $first_payment_timestamp += 3 * HOUR_IN_SECONDS; // And convert it to the UTC equivalent of 3am on that day $first_payment_timestamp -= get_option('gmt_offset') * HOUR_IN_SECONDS; $first_payment = 'mysql' == $type && 0 != $first_payment_timestamp ? date('Y-m-d H:i:s', $first_payment_timestamp) : $first_payment_timestamp; return apply_filters('woocommerce_subscriptions_synced_first_payment_date', $first_payment, $product, $type, $from_date, $from_date_param); }
/** * Uses the details of an order to create a pending subscription on the customers account * for a subscription product, as specified with $product_id. * * @param int|WC_Order $order The order ID or WC_Order object to create the subscription from. * @param int $product_id The ID of the subscription product on the order, if a variation, it must be the variation's ID. * @param array $args An array of name => value pairs to customise the details of the subscription, including: * 'start_date' A MySQL formatted date/time string on which the subscription should start, in UTC timezone * 'expiry_date' A MySQL formatted date/time string on which the subscription should expire, in UTC timezone * @since 1.1 */ public static function create_pending_subscription_for_order($order, $product_id, $args = array()) { _deprecated_function(__METHOD__, '2.0', 'wcs_create_subscription()'); if (!is_object($order)) { $order = new WC_Order($order); } if (!WC_Subscriptions_Product::is_subscription($product_id)) { return; } $args = wp_parse_args($args, array('start_date' => get_gmt_from_date($order->order_date), 'expiry_date' => '')); $billing_period = WC_Subscriptions_Product::get_period($product_id); $billing_interval = WC_Subscriptions_Product::get_interval($product_id); // Support passing timestamps $args['start_date'] = is_numeric($args['start_date']) ? date('Y-m-d H:i:s', $args['start_date']) : $args['start_date']; $product = wc_get_product($product_id); // Check if there is already a subscription for this product and order $subscriptions = wcs_get_subscriptions(array('order_id' => $order->id, 'product_id' => $product_id)); if (!empty($subscriptions)) { $subscription = array_pop($subscriptions); // Make sure the subscription is pending and start date is set correctly wp_update_post(array('ID' => $subscription->id, 'post_status' => 'wc-' . apply_filters('woocommerce_default_subscription_status', 'pending'), 'post_date' => get_date_from_gmt($args['start_date']))); } else { $subscription = wcs_create_subscription(array('start_date' => get_date_from_gmt($args['start_date']), 'order_id' => $order->id, 'customer_id' => $order->get_user_id(), 'billing_period' => $billing_period, 'billing_interval' => $billing_interval, 'customer_note' => $order->customer_note)); if (is_wp_error($subscription)) { throw new Exception(__('Error: Unable to create subscription. Please try again.', 'woocommerce-subscriptions')); } $item_id = $subscription->add_product($product, 1, array('variation' => method_exists($product, 'get_variation_attributes') ? $product->get_variation_attributes() : array(), 'totals' => array('subtotal' => $product->get_price(), 'subtotal_tax' => 0, 'total' => $product->get_price(), 'tax' => 0, 'tax_data' => array('subtotal' => array(), 'total' => array())))); if (!$item_id) { throw new Exception(__('Error: Unable to add product to created subscription. Please try again.', 'woocommerce-subscriptions')); } } // Make sure some of the meta is copied form the order rather than the store's defaults update_post_meta($subscription->id, '_order_currency', $order->order_currency); update_post_meta($subscription->id, '_prices_include_tax', $order->prices_include_tax); // Adding a new subscription so set the expiry date/time from the order date if (!empty($args['expiry_date'])) { if (is_numeric($args['expiry_date'])) { $args['expiry_date'] = date('Y-m-d H:i:s', $args['expiry_date']); } $expiration = $args['expiry_date']; } else { $expiration = WC_Subscriptions_Product::get_expiration_date($product_id, $args['start_date']); } // Adding a new subscription so set the expiry date/time from the order date $trial_expiration = WC_Subscriptions_Product::get_trial_expiration_date($product_id, $args['start_date']); $dates_to_update = array(); if ($trial_expiration > 0) { $dates_to_update['trial_end'] = $trial_expiration; } if ($expiration > 0) { $dates_to_update['end'] = $expiration; } if (!empty($dates_to_update)) { $subscription->update_dates($dates_to_update); } // Set the recurring totals on the subscription $subscription->set_total(0, 'tax'); $subscription->set_total($product->get_price(), 'total'); $subscription->add_order_note(__('Pending subscription created.', 'woocommerce-subscriptions')); do_action('pending_subscription_created_for_order', $order, $product_id); }
/** * Add subscription related order item meta when a subscription product is added as an item to an order via Ajax. * * @param item_id int An order_item_id as returned by the insert statement of @see woocommerce_add_order_item() * @since 1.2.5 * @version 1.4 * @return void */ public static function prefill_order_item_meta($item, $item_id) { $order_id = $_POST['order_id']; $product_id = $item['variation_id'] ? $item['variation_id'] : $item['product_id']; if ($item_id && WC_Subscriptions_Product::is_subscription($product_id)) { $order = new WC_Order($order_id); $_product = get_product($product_id); $recurring_amount = $_product->get_price_excluding_tax(); $sign_up_fee = $_product->get_sign_up_fee_excluding_tax(); $free_trial_length = WC_Subscriptions_Product::get_trial_length($product_id); woocommerce_add_order_item_meta($item_id, '_subscription_period', WC_Subscriptions_Product::get_period($product_id)); woocommerce_add_order_item_meta($item_id, '_subscription_interval', WC_Subscriptions_Product::get_interval($product_id)); woocommerce_add_order_item_meta($item_id, '_subscription_length', WC_Subscriptions_Product::get_length($product_id)); woocommerce_add_order_item_meta($item_id, '_subscription_trial_length', $free_trial_length); woocommerce_add_order_item_meta($item_id, '_subscription_trial_period', WC_Subscriptions_Product::get_trial_period($product_id)); woocommerce_add_order_item_meta($item_id, '_subscription_recurring_amount', $recurring_amount); woocommerce_add_order_item_meta($item_id, '_subscription_sign_up_fee', $sign_up_fee); woocommerce_add_order_item_meta($item_id, '_recurring_line_total', $recurring_amount); woocommerce_add_order_item_meta($item_id, '_recurring_line_tax', 0); woocommerce_add_order_item_meta($item_id, '_recurring_line_subtotal', $recurring_amount); woocommerce_add_order_item_meta($item_id, '_recurring_line_subtotal_tax', 0); WC_Subscriptions_Manager::create_pending_subscription_for_order($order_id, $item['product_id']); switch ($order->status) { case 'completed': case 'processing': woocommerce_update_order_item_meta($item_id, '_subscription_status', 'active'); break; case 'on-hold': woocommerce_update_order_item_meta($item_id, '_subscription_status', 'on-hold'); break; case 'failed': case 'cancelled': woocommerce_add_order_item_meta($item_id, '_subscription_status', 'cancelled'); break; } // We need to override the line totals to $0 when there is a free trial if ($free_trial_length > 0 || $sign_up_fee > 0) { $line_total_keys = array('line_subtotal', 'line_total'); // Make sure sign up fees are included in the total (or $0 if no sign up fee and a free trial) foreach ($line_total_keys as $line_total_key) { $item[$line_total_key] = $sign_up_fee; } // If there is no free trial, make sure line totals include sign up fee and recurring fees if (0 == $free_trial_length) { foreach ($line_total_keys as $line_total_key) { $item[$line_total_key] += $recurring_amount; } } foreach ($line_total_keys as $line_total_key) { $item[$line_total_key] = WC_Subscriptions::format_total($item[$line_total_key], 2); } } else { $item['line_subtotal'] = $recurring_amount; $item['line_total'] = $recurring_amount; } woocommerce_update_order_item_meta($item_id, '_line_subtotal', $item['line_subtotal']); woocommerce_update_order_item_meta($item_id, '_line_total', $item['line_total']); } return $item; }
/** * Add each subscription product's details to an order so that the state of the subscription persists even when a product is changed * * @since 1.2.5 */ public static function add_order_item_meta($item_id, $values) { global $woocommerce; if (!WC_Subscriptions_Cart::cart_contains_subscription_renewal('child') && WC_Subscriptions_Product::is_subscription($values['product_id'])) { $cart_item = $values['data']; $product_id = empty($values['variation_id']) ? $values['product_id'] : $values['variation_id']; // Add subscription details so order state persists even when a product is changed $period = isset($cart_item->subscription_period) ? $cart_item->subscription_period : WC_Subscriptions_Product::get_period($product_id); $interval = isset($cart_item->subscription_period_interval) ? $cart_item->subscription_period_interval : WC_Subscriptions_Product::get_interval($product_id); $length = isset($cart_item->subscription_length) ? $cart_item->subscription_length : WC_Subscriptions_Product::get_length($product_id); $trial_length = isset($cart_item->subscription_trial_length) ? $cart_item->subscription_trial_length : WC_Subscriptions_Product::get_trial_length($product_id); $trial_period = isset($cart_item->subscription_trial_period) ? $cart_item->subscription_trial_period : WC_Subscriptions_Product::get_trial_period($product_id); $sign_up_fee = isset($cart_item->subscription_sign_up_fee) ? $cart_item->subscription_sign_up_fee : WC_Subscriptions_Product::get_sign_up_fee($product_id); woocommerce_add_order_item_meta($item_id, '_subscription_period', $period); woocommerce_add_order_item_meta($item_id, '_subscription_interval', $interval); woocommerce_add_order_item_meta($item_id, '_subscription_length', $length); woocommerce_add_order_item_meta($item_id, '_subscription_trial_length', $trial_length); woocommerce_add_order_item_meta($item_id, '_subscription_trial_period', $trial_period); woocommerce_add_order_item_meta($item_id, '_subscription_recurring_amount', $woocommerce->cart->base_recurring_prices[$product_id]); // WC_Subscriptions_Product::get_price() would return a price without filters applied woocommerce_add_order_item_meta($item_id, '_subscription_sign_up_fee', $sign_up_fee); // Calculated recurring amounts for the item woocommerce_add_order_item_meta($item_id, '_recurring_line_total', $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_total']); woocommerce_add_order_item_meta($item_id, '_recurring_line_tax', $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_tax']); woocommerce_add_order_item_meta($item_id, '_recurring_line_subtotal', $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal']); woocommerce_add_order_item_meta($item_id, '_recurring_line_subtotal_tax', $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_subtotal_tax']); // Add recurring line tax data (for WC 2.2+) $raw_tax_data = $woocommerce->cart->recurring_cart_contents[$values['product_id']]['recurring_line_tax_data']; $recurring_tax_data = array(); $recurring_tax_data['total'] = array_map('wc_format_decimal', $raw_tax_data['total']); $recurring_tax_data['subtotal'] = array_map('wc_format_decimal', $raw_tax_data['subtotal']); woocommerce_add_order_item_meta($item_id, '_recurring_line_tax_data', $recurring_tax_data); } }
/** * Gets the subscription period from the cart and returns it as an array (eg. array( 'month', 'day' ) ) * * Deprecated because a cart can now contain multiple subscription products, so there is no single period for the entire cart. * * @since 1.0 * @deprecated 2.0 */ public static function get_cart_subscription_period() { _deprecated_function(__METHOD__, '2.0', 'values from WC()->cart->recurring_carts'); if (self::cart_contains_subscription()) { foreach (WC()->cart->cart_contents as $cart_item) { if (isset($cart_item['data']->subscription_period)) { $period = $cart_item['data']->subscription_period; break; } elseif (WC_Subscriptions_Product::is_subscription($cart_item['data'])) { $period = WC_Subscriptions_Product::get_period($cart_item['data']); break; } } } return apply_filters('woocommerce_subscriptions_cart_period', $period); }
/** * Return an associative array of a given subscriptions details (if it exists). * * @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key() * @param deprecated don't use * @return array Subscription details * @since 1.1 */ public static function get_subscription($subscription_key, $deprecated = null) { if (null != $deprecated) { _deprecated_argument(__METHOD__, '1.4', __('Second parameter is deprecated', 'woocommerce-subscriptions')); } $item = WC_Subscriptions_Order::get_item_by_subscription_key($subscription_key); if (!empty($item)) { $subscription = array('order_id' => $item['order_id'], 'product_id' => $item['product_id'], 'variation_id' => $item['variation_id'], 'status' => isset($item['subscription_status']) ? $item['subscription_status'] : 'pending', 'period' => isset($item['subscription_period']) ? $item['subscription_period'] : WC_Subscriptions_Product::get_period($item['product_id']), 'interval' => isset($item['subscription_interval']) ? $item['subscription_interval'] : WC_Subscriptions_Product::get_interval($item['product_id']), 'length' => isset($item['subscription_length']) ? $item['subscription_length'] : WC_Subscriptions_Product::get_length($item['product_id']), 'start_date' => isset($item['subscription_start_date']) ? $item['subscription_start_date'] : 0, 'expiry_date' => isset($item['subscription_expiry_date']) ? $item['subscription_expiry_date'] : 0, 'end_date' => isset($item['subscription_end_date']) ? $item['subscription_end_date'] : 0, 'trial_expiry_date' => isset($item['subscription_trial_expiry_date']) ? $item['subscription_trial_expiry_date'] : 0, 'failed_payments' => isset($item['subscription_failed_payments']) ? $item['subscription_failed_payments'] : 0, 'completed_payments' => isset($item['subscription_completed_payments']) ? $item['subscription_completed_payments'] : array(), 'suspension_count' => isset($item['subscription_suspension_count']) ? $item['subscription_suspension_count'] : 0, 'last_payment_date' => isset($item['subscription_completed_payments']) ? end($item['subscription_completed_payments']) : ''); } else { $subscription = array(); } return apply_filters('woocommerce_get_subscription', $subscription, $subscription_key, $deprecated); }
/** * Add each subscription product's details to an order so that the state of the subscription persists even when a product is changed * * @since 1.2 */ public static function add_order_item_meta($order_item) { global $woocommerce; if (WC_Subscriptions_Product::is_subscription($order_item['id'])) { // Make sure existing meta persists $item_meta = new WC_Order_Item_Meta($order_item['item_meta']); // Add subscription details so order state persists even when a product is changed $item_meta->add('_subscription_period', WC_Subscriptions_Product::get_period($order_item['id'])); $item_meta->add('_subscription_interval', WC_Subscriptions_Product::get_interval($order_item['id'])); $item_meta->add('_subscription_length', WC_Subscriptions_Product::get_length($order_item['id'])); $item_meta->add('_subscription_trial_length', WC_Subscriptions_Product::get_trial_length($order_item['id'])); $item_meta->add('_subscription_trial_period', WC_Subscriptions_Product::get_trial_period($order_item['id'])); $item_meta->add('_subscription_recurring_amount', $woocommerce->cart->base_recurring_prices[$order_item['id']]); // WC_Subscriptions_Product::get_price() would return a price without filters applied $item_meta->add('_subscription_sign_up_fee', WC_Subscriptions_Product::get_sign_up_fee($order_item['id'])); // Calculated recurring amounts for the item $item_meta->add('_recurring_line_total', $woocommerce->cart->recurring_cart_contents[$order_item['id']]['recurring_line_total']); $item_meta->add('_recurring_line_tax', $woocommerce->cart->recurring_cart_contents[$order_item['id']]['recurring_line_tax']); $item_meta->add('_recurring_line_subtotal', $woocommerce->cart->recurring_cart_contents[$order_item['id']]['recurring_line_subtotal']); $item_meta->add('_recurring_line_subtotal_tax', $woocommerce->cart->recurring_cart_contents[$order_item['id']]['recurring_line_subtotal_tax']); $order_item['item_meta'] = $item_meta->meta; } return $order_item; }
} ?> <p class="gray fs-18 font-azo"><?php _e($articleObj->getServiceType(), 'project'); ?> </p> <div class="product-price show-mb"> <?php echo apply_filters('woocommerce_cart_item_price', WC()->cart->get_product_price($_product), $cart_item, $cart_item_key); ?> </div> <div class="product-duration show-mb"> <?php $duration = WC_Subscriptions_Product::get_period($_product); $durationLabel = !empty($duration) ? 'continual' : 'one time'; _e($durationLabel, 'woocommerce'); ?> </div> <div class="product-edit show-mb"> <?php echo apply_filters('woocommerce_cart_item_remove_link', sprintf('<a href="%s" data-url="' . $articleObj->getEditUrl() . '" class="edit js-edit-product" title="%s" data-cart-item-key="' . $cart_item_key . '" data-product_id="%s" data-product_sku="%s">EDIT<img src="' . get_template_directory_uri() . '/images/edit-icon.png"/></a>', esc_url(WC()->cart->get_remove_url($cart_item_key)), __('Edit this item', 'woocommerce'), esc_attr($product_id), esc_attr($_product->get_sku())), $cart_item_key); ?> </div> <div class="product-remove show-mb"> <?php echo apply_filters('woocommerce_cart_item_remove_link', sprintf('<a href="%s" class="remove" title="%s" data-product_id="%s" data-product_sku="%s">DELETE<img src="' . get_template_directory_uri() . '/images/remove-icon.png"/></a>', esc_url(WC()->cart->get_remove_url($cart_item_key)), __('Remove this item', 'woocommerce'), esc_attr($product_id), esc_attr($_product->get_sku())), $cart_item_key); ?>
/** * Gets the subscription period from the cart and returns it as an array (eg. array( 'month', 'day' ) ) * * @since 1.0 */ public static function get_cart_subscription_period() { global $woocommerce; foreach ($woocommerce->cart->cart_contents as $cart_item) { if (WC_Subscriptions_Product::is_subscription($cart_item['product_id'])) { $period = WC_Subscriptions_Product::get_period($cart_item['product_id']); break; } } return $period; }
/** Update Member Plan **/ function upd_mem_plan() { global $current_user, $woocommerce, $wpdb; $mess = array(); $mess['act'] = 'success'; parse_str($_POST['form_data'], $d); get_currentuserinfo(); $product_id = $d['meal_plan_type']; $arr = array(); $cur_user_subscription = WC_Subscriptions_Manager::get_users_subscriptions(get_current_user_id()); /* $current_subscription To Cancel all users previous subscription */ foreach ($cur_user_subscription as $suk => $suv) { $orderID = $suv['order_id']; $suv['product_id'] = $d['meal_plan']; $arr[$suv['order_id'] . '_' . $d['meal_plan']] = $suv; update_user_meta(get_current_user_id(), 'wp_woocommerce_subscriptions', $arr); break; } // Create Order (send cart variable so we can record items and reduce inventory). Only create if this is a new order, not if the payment was rejected. $product_id = $d['meal_plan_type']; $_product = new WC_Product($product_id); // Set values $item = array(); // Add line item $srOW = $wpdb->get_row("select * FROM wp_woocommerce_order_items WHERE order_id = " . $orderID); $item_id = $srOW->order_item_id; $args = array('post_type' => 'product', 'post_status' => 'publish'); $loop = new WP_Query($args); $i = 0; if ($loop->have_posts()) { while ($loop->have_posts()) { $loop->the_post(); $____product = get_product(get_the_ID()); $_var[get_the_ID()] = $____product->get_available_variations(); } } wp_reset_query(); foreach ($_var as $_k => $_variations) { foreach ($_variations as $_vk => $_vv) { if ($_vv['variation_id'] == $product_id) { $variation_name = $_vv['attributes']['attribute_servings']; $p = strip_tags($_vv['price_html']); } } } // update post meta for pricing update_post_meta($orderID, '_order_total', get_post_meta($product_id, '_price', true)); update_post_meta($orderID, '_order_recurring_total', get_post_meta($product_id, '_subscription_price', true)); // Add subscription details so order state persists even when a product is changed $period = WC_Subscriptions_Product::get_period($product_id); $interval = WC_Subscriptions_Product::get_interval($product_id); $length = WC_Subscriptions_Product::get_length($product_id); $trial_length = WC_Subscriptions_Product::get_trial_length($product_id); $trial_period = WC_Subscriptions_Product::get_trial_period($product_id); $sign_up_fee = WC_Subscriptions_Product::get_sign_up_fee($product_id); woocommerce_update_order_item_meta($item_id, '_qty', 1); woocommerce_update_order_item_meta($item_id, '_tax_class', ''); woocommerce_update_order_item_meta($item_id, '_product_id', $d['meal_plan']); woocommerce_update_order_item_meta($item_id, '_variation_id', $product_id); woocommerce_update_order_item_meta($item_id, '_line_subtotal', get_post_meta($product_id, '_price', true)); woocommerce_update_order_item_meta($item_id, '_line_total', get_post_meta($product_id, '_subscription_price', true)); // WC_Subscriptions_Product::get_price() would return a price without filters applied woocommerce_update_order_item_meta($item_id, '_line_tax', 0); woocommerce_update_order_item_meta($item_id, '_line_subtotal_tax', 0); // WC_Subscriptions_Product::get_price() would return a price without filters applied woocommerce_update_order_item_meta($item_id, 'Servings:', $variation_name); woocommerce_update_order_item_meta($item_id, '_subscription_period', $period); woocommerce_update_order_item_meta($item_id, '_subscription_interval', $interval); woocommerce_update_order_item_meta($item_id, '_subscription_length', $length); woocommerce_update_order_item_meta($item_id, '_subscription_trial_length', $trial_length); woocommerce_update_order_item_meta($item_id, '_subscription_trial_period', $trial_period); woocommerce_update_order_item_meta($item_id, '_subscription_recurring_amount', get_post_meta($product_id, '_subscription_price', true)); // WC_Subscriptions_Product::get_price() would return a price without filters applied woocommerce_update_order_item_meta($item_id, '_subscription_sign_up_fee', $sign_up_fee); // Calculated recurring amounts for the item woocommerce_update_order_item_meta($item_id, '_recurring_line_total', number_format((double) get_post_meta($product_id, '_price', true), 2, '.', '')); woocommerce_update_order_item_meta($item_id, '_recurring_line_tax', ''); woocommerce_update_order_item_meta($item_id, '_recurring_line_subtotal', number_format((double) get_post_meta($product_id, '_regular_price', true), 2, '.', '')); woocommerce_update_order_item_meta($item_id, '_recurring_line_subtotal_tax', ''); $odr = $orderID; /* Fetch Oder Details */ //if(($_vv['variation_id'] == $vari_ID)) $mealOrder = woocommerce_get_order_item_meta($srOW->order_item_id, 'Servings:', true); $mealType = woocommerce_get_order_item_meta($srOW->order_item_id, '_subscription_period', true); $mealTotal = woocommerce_get_order_item_meta($srOW->order_item_id, '_recurring_line_subtotal', true); $vari_ID = woocommerce_get_order_item_meta($srOW->order_item_id, '_variation_id', true); $_product = get_product($product_id); $srOW = $wpdb->get_row("UPDATE wp_woocommerce_order_items SET order_item_name = '" . $_product->post->post_title . "' WHERE order_item_id=" . $item_id); $html = '<div class="info_heading">Meal Plan</div> <div class="info_values"> <p>' . $_product->post->post_title . '</p> </div> <div class="info_heading">Subscriptions Type</div> <div class="info_values"> <p>' . $variation_name . '</p> </div> <div class="info_heading">Price</div> <div class="info_values"> <p>' . $p . '</p> </div>'; $mess['message'] = $html; echo json_encode($mess); exit; }
/** * Add subscription related order item meta via Ajax when a subscription product is added as an item to an order. * * This function is hooked to the 'wp_ajax_woocommerce_subscriptions_prefill_order_item_meta' hook which should only fire * on WC 1.x (because the admin.js uses a selector which was changed in WC 2.0). For WC 2.0, order item meta is pre-filled * via the 'woocommerce_new_order_item' hook in the new @see self::prefill_order_item(). * * @since 1.2.4 * @return void */ public static function prefill_order_item_meta_old() { if (function_exists('woocommerce_add_order_item_meta')) { // Meta added on the 'woocommerce_new_order_item' hook return; } check_ajax_referer(WC_Subscriptions::$text_domain, 'security'); $product_id = trim(stripslashes($_POST['item_to_add'])); $index = trim(stripslashes($_POST['index'])); $response = array('item_index' => $index, 'html' => '', 'line_totals' => array()); if (WC_Subscriptions_Product::is_subscription($product_id)) { $recurring_amount = WC_Subscriptions_Product::get_price($product_id); $item_meta = new WC_Order_Item_Meta(); // Subscription details so order state persists even when a product is changed $item_meta->add('_subscription_period', WC_Subscriptions_Product::get_period($product_id)); $item_meta->add('_subscription_interval', WC_Subscriptions_Product::get_interval($product_id)); $item_meta->add('_subscription_length', WC_Subscriptions_Product::get_length($product_id)); $item_meta->add('_subscription_trial_length', WC_Subscriptions_Product::get_trial_length($product_id)); $item_meta->add('_subscription_trial_period', WC_Subscriptions_Product::get_trial_period($product_id)); $item_meta->add('_subscription_recurring_amount', $recurring_amount); $item_meta->add('_subscription_sign_up_fee', WC_Subscriptions_Product::get_sign_up_fee($product_id)); // Recurring totals need to be calcualted $item_meta->add('_recurring_line_total', $recurring_amount); $item_meta->add('_recurring_line_tax', 0); $item_meta->add('_recurring_line_subtotal', $recurring_amount); $item_meta->add('_recurring_line_subtotal_tax', 0); $item_meta = $item_meta->meta; if (isset($item_meta) && is_array($item_meta) && sizeof($item_meta) > 0) { foreach ($item_meta as $key => $meta) { // Backwards compatibility if (is_array($meta) && isset($meta['meta_name'])) { $meta_name = $meta['meta_name']; $meta_value = $meta['meta_value']; } else { $meta_name = $key; $meta_value = $meta; } $response['html'] .= '<tr><td><input type="text" name="meta_name[' . $index . '][]" value="' . esc_attr($meta_name) . '" /></td><td><input type="text" name="meta_value[' . $index . '][]" value="' . esc_attr($meta_value) . '" /></td><td width="1%"></td></tr>'; } } // Calculate line totals for this item if ($sign_up_fee > 0) { $line_subtotal = $sign_up_fee; $line_total = $sign_up_fee; // If there is no free trial, add the recuring amounts if ($trial_length == 0) { $line_subtotal += $recurring_amount; $line_total += $recurring_amount; } $response['line_totals']['line_subtotal'] = esc_attr(number_format((double) $line_subtotal, 2, '.', '')); $response['line_totals']['line_total'] = esc_attr(number_format((double) $line_total, 2, '.', '')); } } echo json_encode($response); die; }
/** * Output * * @since 1.5 */ public static function products_first_payment_date($echo = false) { global $product; $first_payment_date = ''; if (self::is_product_synced($product)) { $first_payment_timestamp = self::calculate_first_payment_date($product->id, 'timestamp'); if (self::is_today($first_payment_timestamp)) { $payment_date_string = __('Today!', 'woocommerce-subscriptions'); } else { $payment_date_string = date_i18n(woocommerce_date_format(), $first_payment_timestamp + get_option('gmt_offset') * HOUR_IN_SECONDS); } if (0 != $first_payment_timestamp) { switch (WC_Subscriptions_Product::get_period($product)) { case 'week': $first_payment_date = sprintf(__('First weekly payment: %s', 'woocommerce-subscriptions'), $payment_date_string); break; case 'month': $first_payment_date = sprintf(__('First monthly payment: %s', 'woocommerce-subscriptions'), $payment_date_string); break; case 'year': $first_payment_date = sprintf(__('First yearly payment: %s', 'woocommerce-subscriptions'), $payment_date_string); break; } $first_payment_date = '<p class="first-payment-date">' . $first_payment_date . '</p>'; } } if (false !== $echo) { echo $first_payment_date; } return $first_payment_date; }
private function print_price_fields($product_id = 0, $form_prefix = "") { if (!$product_id) { global $product; if ($product) { $product_id = $product->id; } } else { $product = wc_get_product($product_id); } if (!$product_id || empty($product)) { return; } if ($this->cpf && $this->tm_epo_enable_final_total_box_all == "no") { $global_price_array = $this->cpf['global']; $local_price_array = $this->cpf['local']; if (empty($global_price_array) && empty($local_price_array)) { return; } } if ($form_prefix) { $form_prefix = "_" . $form_prefix; } // WooCommerce Dynamic Pricing & Discounts if (class_exists('RP_WCDPD') && !empty($GLOBALS['RP_WCDPD'])) { $price = $this->get_RP_WCDPD($product); if ($price) { $price['product'] = array(); if ($price['is_multiprice']) { foreach ($price['rules'] as $variation_id => $variation_rule) { foreach ($variation_rule as $rulekey => $pricerule) { $price['product'][$variation_id][] = array("min" => $pricerule["min"], "max" => $pricerule["max"], "value" => $pricerule["type"] != "percentage" ? apply_filters('woocommerce_tm_epo_price', $pricerule["value"], "") : $pricerule["value"], "type" => $pricerule["type"]); } } } else { foreach ($price['rules'] as $rulekey => $pricerule) { $price['product'][0][] = array("min" => $pricerule["min"], "max" => $pricerule["max"], "value" => $pricerule["type"] != "percentage" ? apply_filters('woocommerce_tm_epo_price', $pricerule["value"], "") : $pricerule["value"], "type" => $pricerule["type"]); } } } else { $price = array(); $price['product'] = array(); } $price['price'] = apply_filters('woocommerce_tm_epo_price', $product->get_price(), ""); } else { if (class_exists('WC_Dynamic_Pricing')) { $id = isset($product->variation_id) ? $product->variation_id : $product->id; $dp = WC_Dynamic_Pricing::instance(); if ($dp && is_object($dp) && property_exists($dp, "discounted_products") && isset($dp->discounted_products[$id])) { $_price = $dp->discounted_products[$id]; } else { $_price = $product->get_price(); } } else { $_price = $product->get_price(); } $price = array(); $price['product'] = array(); $price['price'] = apply_filters('woocommerce_tm_epo_price', $_price, ""); } $variations = array(); $variations_subscription_period = array(); $variations_subscription_sign_up_fee = array(); foreach ($product->get_children() as $child_id) { $variation = $product->get_child($child_id); if (!$variation->exists()) { continue; } $variations[$child_id] = apply_filters('woocommerce_tm_epo_price', $variation->get_price(), ""); $variations_subscription_period[$child_id] = $variation->subscription_period; $variations_subscription_sign_up_fee[$child_id] = $variation->subscription_sign_up_fee; } $is_subscription = false; $subscription_period = ''; $subscription_sign_up_fee = 0; if (class_exists('WC_Subscriptions_Product')) { if (WC_Subscriptions_Product::is_subscription($product)) { $is_subscription = true; $subscription_period = WC_Subscriptions_Product::get_period($product); $subscription_sign_up_fee = WC_Subscriptions_Product::get_sign_up_fee($product); } } global $woocommerce; $cart = $woocommerce->cart; $_tax = new WC_Tax(); $taxrates = $_tax->get_rates($product->get_tax_class()); unset($_tax); $tax_rate = 0; foreach ($taxrates as $key => $value) { $tax_rate = $tax_rate + floatval($value['rate']); } $taxable = $product->is_taxable(); $tax_display_mode = get_option('woocommerce_tax_display_shop'); $tax_string = ""; if ($taxable) { if ($tax_display_mode == 'excl') { //if ( $cart->tax_total > 0 && $cart->prices_include_tax ) { $tax_string = ' <small>' . WC()->countries->ex_tax_or_vat() . '</small>'; //} } else { //if ( $cart->tax_total > 0 && !$cart->prices_include_tax ) { $tax_string = ' <small>' . WC()->countries->inc_tax_or_vat() . '</small>'; //} } } $force_quantity = 0; if (isset($_GET['tm_cart_item_key'])) { $cart_item_key = $_GET['tm_cart_item_key']; $cart_item = WC()->cart->get_cart_item($cart_item_key); if (isset($cart_item["quantity"])) { $force_quantity = $cart_item["quantity"]; } } wc_get_template('tm-totals.php', array('theme_name' => $this->get_theme('Name'), 'variations' => esc_html(json_encode((array) $variations)), 'variations_subscription_period' => esc_html(json_encode((array) $variations_subscription_period)), 'variations_subscription_sign_up_fee' => esc_html(json_encode((array) $variations_subscription_sign_up_fee)), 'subscription_period' => $subscription_period, 'subscription_sign_up_fee' => $subscription_sign_up_fee, 'is_subscription' => $is_subscription, 'is_sold_individually' => $product->is_sold_individually(), 'hidden' => $this->tm_meta_cpf['override_final_total_box'] ? $this->tm_epo_final_total_box == 'hide' ? ' hidden' : '' : ($this->tm_meta_cpf['override_final_total_box'] == 'hide' ? ' hidden' : ''), 'form_prefix' => $form_prefix, 'type' => esc_html($product->product_type), 'price' => esc_html(is_object($product) ? apply_filters('woocommerce_tm_final_price', $price['price'], $product) : ''), 'taxable' => $taxable, 'tax_display_mode' => $tax_display_mode, 'prices_include_tax' => $cart->prices_include_tax, 'tax_rate' => $tax_rate, 'tax_string' => $tax_string, 'product_price_rules' => esc_html(json_encode((array) $price['product'])), 'fields_price_rules' => $this->tm_epo_dpd_enable == "no" ? 0 : 1, 'tm_epo_dpd_suffix' => $this->tm_epo_dpd_suffix, 'tm_epo_dpd_prefix' => $this->tm_epo_dpd_prefix, 'force_quantity' => $force_quantity), $this->_namespace, $this->template_path); if ($this->is_quick_view()) { remove_filter('wp_footer', array($this, 'tm_add_inline_style'), 99999); $this->tm_add_inline_style(); } }