/** * Remove order item meta * * @access public * @return HTML * @since 8.1.02 */ public function remove_order_item_meta($item_id, $cart_item) { $shipping_method = WC()->session->get('chosen_shipping_methods'); if (strpos($shipping_method[0], 'jne') === false) { if (!empty($cart_item['jne_asuransi'])) { woocommerce_delete_order_item_meta($item_id, __('JNE Asuransi', 'woocommerce-jne')); } } }
/** * Save entered credit value by customer in order for further processing * * @param int $order_id * @param array $posted associative array of posted data */ public function save_called_credit_details_in_order($order_id, $posted) { $order = $this->get_order($order_id); $order_items = $order->get_items(); $sc_called_credit = array(); $update = false; foreach ($order_items as $item_id => $order_item) { if (isset($order_item['sc_called_credit']) && !empty($order_item['sc_called_credit'])) { $sc_called_credit[$item_id] = $order_item['sc_called_credit']; woocommerce_delete_order_item_meta($item_id, 'sc_called_credit'); $update = true; } } if ($update) { update_post_meta($order_id, 'sc_called_credit_details', $sc_called_credit); } if (function_exists('get_product')) { if (isset($this->global_wc()->session->credit_called)) { unset($this->global_wc()->session->credit_called); } } else { if (isset($_SESSION['credit_called'])) { unset($_SESSION['credit_called']); } } }
/** * Create and redirect to an invoice */ public function order_action_handler() { global $wpdb; $action = false; $item_id = false; if (!empty($_GET['mark_deposit_unpaid']) && isset($_GET['mark_deposit_unpaid_nonce']) && wp_verify_nonce($_GET['mark_deposit_unpaid_nonce'], 'mark_deposit_unpaid')) { $action = 'mark_deposit_unpaid'; $item_id = absint($_GET['mark_deposit_unpaid']); } if (!empty($_GET['mark_deposit_fully_paid']) && isset($_GET['mark_deposit_fully_paid_nonce']) && wp_verify_nonce($_GET['mark_deposit_fully_paid_nonce'], 'mark_deposit_fully_paid')) { $action = 'mark_deposit_fully_paid'; $item_id = absint($_GET['mark_deposit_fully_paid']); } if (!empty($_GET['invoice_remaining_balance']) && isset($_GET['invoice_remaining_balance_nonce']) && wp_verify_nonce($_GET['invoice_remaining_balance_nonce'], 'invoice_remaining_balance')) { $action = 'invoice_remaining_balance'; $item_id = absint($_GET['invoice_remaining_balance']); } if (!$item_id) { return; } $order_id = $wpdb->get_var($wpdb->prepare("SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id)); $order = wc_get_order($order_id); $item = false; foreach ($order->get_items() as $order_item_id => $order_item) { if ($item_id === $order_item_id) { $item = $order_item; } } if (!$item || empty($item['is_deposit'])) { return; } switch ($action) { case 'mark_deposit_unpaid': woocommerce_delete_order_item_meta($item_id, '_remaining_balance_paid', 1, true); wp_redirect(admin_url('post.php?post=' . absint($order_id) . '&action=edit')); exit; case 'mark_deposit_fully_paid': woocommerce_add_order_item_meta($item_id, '_remaining_balance_paid', 1); wp_redirect(admin_url('post.php?post=' . absint($order_id) . '&action=edit')); exit; case 'invoice_remaining_balance': $create_item = array('product' => $order->get_product_from_item($item), 'qty' => $item['qty'], 'amount' => $item['deposit_full_amount_ex_tax'] - $order->get_line_total($item, false)); $new_order_id = $this->create_order(current_time('timestamp'), $order_id, 2, $create_item); woocommerce_add_order_item_meta($item_id, '_remaining_balance_order_id', $new_order_id); // Email invoice $emails = WC_Emails::instance(); $emails->customer_invoice(wc_get_order($new_order_id)); wp_redirect(admin_url('post.php?post=' . absint($new_order_id) . '&action=edit')); exit; } }
/** * Use views to display the Orders page * * @return html */ public function display_product_orders() { if (!WCV_Vendors::is_vendor(get_current_user_id())) { ob_start(); wc_get_template('denied.php', array(), 'wc-vendors/dashboard/', wcv_plugin_dir . 'templates/dashboard/'); return ob_get_clean(); } if (empty($_GET['orders_for_product'])) { return __('You haven\'t selected a product\'s orders to view! Please go back to the Vendor Dashboard and click Show Orders on the product you\'d like to view.', 'wcvendors'); } if (!$this->orders) { return __('No orders.', 'wcvendors'); } if (!empty($_POST['submit_comment'])) { require_once wcv_plugin_dir . 'classes/front/orders/class-submit-comment.php'; WCV_Submit_Comment::new_comment($this->orders); } if (isset($_POST['mark_shipped'])) { $order_id = (int) $_POST['order_id']; $product_id = (int) $_POST['product_id']; exit; } if (isset($_POST['update_tracking'])) { $order_id = (int) $_POST['order_id']; $product_id = (int) $_POST['product_id']; $tracking_provider = woocommerce_clean($_POST['tracking_provider']); $custom_tracking_provider = woocommerce_clean($_POST['custom_tracking_provider']); $custom_tracking_link = woocommerce_clean($_POST['custom_tracking_link']); $tracking_number = woocommerce_clean($_POST['tracking_number']); $date_shipped = woocommerce_clean(strtotime($_POST['date_shipped'])); $order = new WC_Order($order_id); $products = $order->get_items(); foreach ($products as $key => $value) { if ($value['product_id'] == $product_id || $value['variation_id'] == $product_id) { $order_item_id = $key; break; } } if ($order_item_id) { woocommerce_delete_order_item_meta($order_item_id, __('Tracking number', 'wcvendors')); woocommerce_add_order_item_meta($order_item_id, __('Tracking number', 'wcvendors'), $tracking_number); $message = __('Success. Your tracking number has been updated.', 'wcvendors'); wc_add_notice($message, 'success'); // Update order data update_post_meta($order_id, '_tracking_provider', $tracking_provider); update_post_meta($order_id, '_custom_tracking_provider', $custom_tracking_provider); update_post_meta($order_id, '_tracking_number', $tracking_number); update_post_meta($order_id, '_custom_tracking_link', $custom_tracking_link); update_post_meta($order_id, '_date_shipped', $date_shipped); } } $headers = WCV_Orders::get_headers(); $all = WCV_Orders::format_order_details($this->orders, $this->product_id); wp_enqueue_style('pv_frontend_style', wcv_assets_url . 'css/wcv-frontend.css'); wp_enqueue_script('pv_frontend_script', wcv_assets_url . 'js/front-orders.js'); // WC Shipment Tracking Providers global $WC_Shipment_Tracking; $providers = !empty($WC_Shipment_Tracking->providers) ? $WC_Shipment_Tracking->providers : false; $provider_array = array(); if ($providers) { foreach ($providers as $providerss) { foreach ($providerss as $provider => $format) { $provider_array[sanitize_title($provider)] = urlencode($format); } } } // End ob_start(); // Show the Export CSV button if ($this->can_export_csv) { wc_get_template('csv-export.php', array(), 'wc-vendors/orders/', wcv_plugin_dir . 'templates/orders/'); } wc_get_template('orders.php', array('headers' => $headers, 'body' => $all['body'], 'items' => $all['items'], 'product_id' => $all['product_id'], 'providers' => $providers, 'provider_array' => $provider_array), 'wc-vendors/orders/', wcv_plugin_dir . 'templates/orders/'); return ob_get_clean(); }
public function save_vendor_settings() { global $woocommerce; $user_id = get_current_user_id(); if (!empty($_GET['wc_pv_mark_shipped'])) { $shop_name = WCV_Vendors::get_vendor_shop_name($user_id); $order_id = $_GET['wc_pv_mark_shipped']; $shippers = (array) get_post_meta($order_id, 'wc_pv_shipped', true); $order = new WC_Order($order_id); // If not in the shippers array mark as shipped otherwise do nothing. if (!in_array($user_id, $shippers)) { $shippers[] = $user_id; $mails = $woocommerce->mailer()->get_emails(); if (!empty($mails)) { $mails['WC_Email_Notify_Shipped']->trigger($order_id, $user_id); } do_action('wcvendors_vendor_ship', $order_id, $user_id); wc_add_notice(__('Order marked shipped.', 'wcvendors'), 'success'); $order->add_order_note(apply_filters('wcvendors_vendor_shipped_note', __($shop_name . ' has marked as shipped. ', 'wcvendors')), $user_id); } elseif (false != ($key = array_search($user_id, $shippers))) { unset($shippers[$key]); // Remove user from the shippers array } update_post_meta($order_id, 'wc_pv_shipped', $shippers); return; } if (isset($_POST['update_tracking'])) { $order_id = (int) $_POST['order_id']; $product_id = (int) $_POST['product_id']; $tracking_provider = woocommerce_clean($_POST['tracking_provider']); $custom_tracking_provider = woocommerce_clean($_POST['custom_tracking_provider_name']); $custom_tracking_link = woocommerce_clean($_POST['custom_tracking_url']); $tracking_number = woocommerce_clean($_POST['tracking_number']); $date_shipped = woocommerce_clean(strtotime($_POST['date_shipped'])); $order = new WC_Order($order_id); $products = $order->get_items(); foreach ($products as $key => $value) { if ($value['product_id'] == $product_id || $value['variation_id'] == $product_id) { $order_item_id = $key; break; } } if ($order_item_id) { woocommerce_delete_order_item_meta($order_item_id, __('Tracking number', 'wcvendors')); woocommerce_add_order_item_meta($order_item_id, __('Tracking number', 'wcvendors'), $tracking_number); $message = __('Success. Your tracking number has been updated.', 'wcvendors'); wc_add_notice($message, 'success'); // Update order data update_post_meta($order_id, '_tracking_provider', $tracking_provider); update_post_meta($order_id, '_custom_tracking_provider', $custom_tracking_provider); update_post_meta($order_id, '_tracking_number', $tracking_number); update_post_meta($order_id, '_custom_tracking_link', $custom_tracking_link); update_post_meta($order_id, '_date_shipped', $date_shipped); } } if (empty($_POST['vendor_application_submit'])) { return false; } if (isset($_POST['wc-product-vendor-nonce'])) { if (!wp_verify_nonce($_POST['wc-product-vendor-nonce'], 'save-shop-settings')) { return false; } if (isset($_POST['pv_paypal'])) { if (!is_email($_POST['pv_paypal'])) { wc_add_notice(__('Your PayPal address is not a valid email address.', 'wcvendors'), 'error'); } else { update_user_meta($user_id, 'pv_paypal', $_POST['pv_paypal']); } } if (!empty($_POST['pv_shop_name'])) { $users = get_users(array('meta_key' => 'pv_shop_slug', 'meta_value' => sanitize_title($_POST['pv_shop_name']))); if (!empty($users) && $users[0]->ID != $user_id) { wc_add_notice(__('That shop name is already taken. Your shop name must be unique.', 'wcvendors'), 'error'); } else { update_user_meta($user_id, 'pv_shop_name', $_POST['pv_shop_name']); update_user_meta($user_id, 'pv_shop_slug', sanitize_title($_POST['pv_shop_name'])); } } if (isset($_POST['pv_shop_description'])) { update_user_meta($user_id, 'pv_shop_description', $_POST['pv_shop_description']); } if (isset($_POST['pv_seller_info'])) { update_user_meta($user_id, 'pv_seller_info', $_POST['pv_seller_info']); } do_action('wcvendors_shop_settings_saved', $user_id); if (!wc_notice_count()) { wc_add_notice(__('Settings saved.', 'wcvendors'), 'success'); } } }
/** * 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. 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.', WC_Subscriptions::$text_domain)); $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 – %s', WC_Subscriptions::$text_domain), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', WC_Subscriptions::$text_domain))), 'post_status' => 'publish', 'ping_status' => 'closed', 'post_excerpt' => $original_order->customer_note, 'post_author' => 1, 'post_password' => $renewal_order_key); $create_new_order = true; 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']; /* 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'; /* If paying on a pending order, we are resuming */ if ($order_status == 'pending') { $renewal_order_id = $failed_order_id; } } if ($renewal_order_id) { /* 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'; // 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); } // 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); if (true === $args['checkout_renewal']) { $checkout_object = $woocommerce->checkout; $customer_id = $original_order->customer_user; // Save posted billing fields to both renewal and original order if ($checkout_object->checkout_fields['billing']) { foreach ($checkout_object->checkout_fields['billing'] as $key => $field) { update_post_meta($renewal_order_id, '_' . $key, $checkout_object->posted[$key]); update_post_meta($original_order->id, '_' . $key, $checkout_object->posted[$key]); // User if ($customer_id && !empty($checkout_object->posted[$key])) { update_user_meta($customer_id, $key, $checkout_object->posted[$key]); // Special fields switch ($key) { case "billing_email": if (!email_exists($checkout_object->posted[$key])) { wp_update_user(array('ID' => $customer_id, 'user_email' => $checkout_object->posted[$key])); } break; case "billing_first_name": wp_update_user(array('ID' => $customer_id, 'first_name' => $checkout_object->posted[$key])); break; case "billing_last_name": wp_update_user(array('ID' => $customer_id, 'last_name' => $checkout_object->posted[$key])); break; } } } } // Save posted shipping fields to both renewal and original order if ($checkout_object->checkout_fields['shipping'] && ($woocommerce->cart->needs_shipping() || get_option('woocommerce_require_shipping_address') == 'yes')) { foreach ($checkout_object->checkout_fields['shipping'] as $key => $field) { $postvalue = false; if ($checkout_object->posted['shiptobilling']) { if (isset($checkout_object->posted[str_replace('shipping_', 'billing_', $key)])) { $postvalue = $checkout_object->posted[str_replace('shipping_', 'billing_', $key)]; update_post_meta($renewal_order_id, '_' . $key, $postvalue); update_post_meta($original_order->id, '_' . $key, $postvalue); } } else { $postvalue = $checkout_object->posted[$key]; update_post_meta($renewal_order_id, '_' . $key, $postvalue); update_post_meta($original_order->id, '_' . $key, $postvalue); } // User if ($postvalue && $customer_id) { update_user_meta($customer_id, $key, $postvalue); } } } } $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')"; // 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); if (true === $args['checkout_renewal']) { $failed_payment_multiplier = 1; update_post_meta($renewal_order_id, '_order_shipping', woocommerce_format_total($woocommerce->cart->shipping_total)); update_post_meta($renewal_order_id, '_order_discount', woocommerce_format_total($woocommerce->cart->get_order_discount_total())); update_post_meta($renewal_order_id, '_cart_discount', woocommerce_format_total($woocommerce->cart->get_cart_discount_total())); update_post_meta($renewal_order_id, '_order_tax', woocommerce_format_total($woocommerce->cart->tax_total)); update_post_meta($renewal_order_id, '_order_shipping_tax', woocommerce_format_total($woocommerce->cart->shipping_tax_total)); update_post_meta($renewal_order_id, '_order_total', woocommerce_format_total($woocommerce->cart->total)); update_post_meta($renewal_order_id, '_checkout_renewal', 'yes'); } else { // 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); } else { $failed_payment_multiplier = 1; } // Set order totals based on recurring totals from the original order $cart_discount = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_discount_cart', true); $order_discount = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_discount_total', true); $order_shipping_tax = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_shipping_tax_total', true); $order_shipping = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_shipping_total', true); $order_tax = $failed_payment_multiplier * get_post_meta($original_order->id, '_order_recurring_tax_total', true); $order_total = $failed_payment_multiplier * 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); 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); // 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) { if (function_exists('woocommerce_update_order_item_meta')) { // WC 2.0+ $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', woocommerce_clean($failed_payment_multiplier * $recurring_order_tax['tax_amount'])); woocommerce_add_order_item_meta($item_id, 'shipping_tax_amount', woocommerce_clean($failed_payment_multiplier * $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']); } } } else { // WC 1.x if (isset($recurring_order_tax['cart_tax']) && $recurring_order_tax['cart_tax'] > 0) { $recurring_order_taxes[$index]['cart_tax'] = $failed_payment_multiplier * $recurring_order_tax['cart_tax']; } else { $recurring_order_taxes[$index]['cart_tax'] = 0; } if (isset($recurring_order_tax['shipping_tax']) && $recurring_order_tax['shipping_tax'] > 0) { $recurring_order_taxes[$index]['shipping_tax'] = $failed_payment_multiplier * $recurring_order_tax['shipping_tax']; } else { $recurring_order_taxes[$index]['shipping_tax'] = 0; } // Inefficient but keeps WC 1.x code grouped together update_post_meta($renewal_order_id, '_order_taxes', $recurring_order_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']); foreach ($order_items as $item_index => $order_item) { $item_meta = new WC_Order_Item_Meta($order_item['item_meta']); // WC 2.0+ order item structure - as of WC 2.0 item_meta is stored as $key => meta pairs, not 'meta_name'/'meta_value' if (function_exists('woocommerce_add_order_item_meta')) { if ('child' == $args['new_order_role']) { $renewal_order_item_name = sprintf(__('Renewal of "%s" purchased in Order %s', WC_Subscriptions::$text_domain), $order_item['name'], $original_order->get_order_number()); } else { $renewal_order_item_name = $order_item['name']; } // 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')); // Remove recurring line items and set item totals based on recurring line totals foreach ($item_meta->meta as $meta_key => $meta) { // $meta is an array, so the item needs to be extracted from $meta[0] (just like order meta on a WC Order) $meta_value = $meta[0]; // Map line item totals based on recurring line totals switch ($meta_key) { case '_recurring_line_total': woocommerce_delete_order_item_meta($recurring_item_id, '_line_total'); woocommerce_add_order_item_meta($recurring_item_id, '_line_total', woocommerce_format_decimal($failed_payment_multiplier * $meta_value)); break; case '_recurring_line_tax': woocommerce_delete_order_item_meta($recurring_item_id, '_line_tax'); woocommerce_add_order_item_meta($recurring_item_id, '_line_tax', woocommerce_format_decimal($failed_payment_multiplier * $meta_value)); break; case '_recurring_line_subtotal': woocommerce_delete_order_item_meta($recurring_item_id, '_line_subtotal'); woocommerce_add_order_item_meta($recurring_item_id, '_line_subtotal', woocommerce_format_decimal($failed_payment_multiplier * $meta_value)); break; case '_recurring_line_subtotal_tax': woocommerce_delete_order_item_meta($recurring_item_id, '_line_subtotal_tax'); woocommerce_add_order_item_meta($recurring_item_id, '_line_subtotal_tax', woocommerce_format_decimal($failed_payment_multiplier * $meta_value)); 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 '_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) { woocommerce_add_order_item_meta($recurring_item_id, $meta_key, $meta_value); } } } else { // WC 1.x order item structure foreach ($item_meta->meta as $meta_index => $meta_item) { switch ($meta_item['meta_name']) { case '_recurring_line_total': $order_items[$item_index]['line_total'] = $failed_payment_multiplier * $meta_item['meta_value']; case '_recurring_line_tax': $order_items[$item_index]['line_tax'] = $failed_payment_multiplier * $meta_item['meta_value']; case '_recurring_line_subtotal': $order_items[$item_index]['line_subtotal'] = $failed_payment_multiplier * $meta_item['meta_value']; case '_recurring_line_subtotal_tax': $order_items[$item_index]['line_subtotal_tax'] = $failed_payment_multiplier * $meta_item['meta_value']; case '_recurring_line_total': case '_recurring_line_tax': case '_recurring_line_subtotal': case '_recurring_line_subtotal_tax': case '_recurring_line_subtotal_tax': case '_subscription_recurring_amount': case '_subscription_sign_up_fee': case '_subscription_period': case '_subscription_interval': case '_subscription_length': case '_subscription_trial_length': case '_subscription_trial_period': if ('child' == $args['new_order_role']) { unset($item_meta->meta[$meta_index]); } break; case '_subscription_trial_length': // We never want to duplicate free trials on renewal orders if ('child' == $args['new_order_role']) { unset($item_meta->meta[$meta_index]); } else { $item_meta->meta[$meta_index] = 0; } break; } if ('child' == $args['new_order_role']) { $order_items[$item_index]['name'] = sprintf(__('Renewal of "%s" purchased in Order %s', WC_Subscriptions::$text_domain), $order_item['name'], $original_order->get_order_number()); } $order_items[$item_index]['item_meta'] = $item_meta->meta; } // Save the item meta on the new order update_post_meta($renewal_order_id, '_order_items', $order_items); } } // 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.', WC_Subscriptions::$text_domain), $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']); }