Woocommerce: add items to processing orders

This only works if the customer has processing cash on delivery orders

    
add_action('woocommerce_before_checkout_form', 'check_for_existing_cod_orders'); function check_for_existing_cod_orders() { if (is_user_logged_in()) { $user_id = get_current_user_id(); $args = array( 'customer_id' => $user_id, 'status' => 'processing', 'payment_method' => 'cod', ); $orders = wc_get_orders($args); if (!empty($orders)) { echo '<div class="woocommerce-info" style="margin-bottom: 20px;">'; echo '<p>'; echo __('You already have the following order(s) processing with Cash on Delivery. Would you like to add your new items in any of these orders?'); echo '</p>'; echo '<p><i class="fa-solid fa-check" style="color: #23c021;"></i> No additional shipping cost <i class="fa-solid fa-check" style="color: #23c021;"></i> Faster shipping</p>'; $cart_subtotal_incl_tax = WC()->cart->get_cart_contents_total() + WC()->cart->get_cart_contents_tax(); foreach ($orders as $order) { $order_id = $order->get_id(); $order_date = $order->get_date_created()->date('Y-m-d H:i:s'); $payment_method = $order->get_payment_method_title(); $order_total = $order->get_total(); $new_total = $order_total + $cart_subtotal_incl_tax; echo '<div style="margin-bottom: 10px; border: 1px solid #ddd; padding: 10px; background-color: white; color: black;">'; echo '<p><strong>Order #' . $order_id . '</strong> - ' . $order_date . ' - Total: ' . wc_price($order_total) . ' - New Total: ' . wc_price($new_total) . '</p>'; echo '<a href="' . esc_url(add_query_arg('combine_order', $order_id)) . '" class="button combine-order-button" style="margin-left: 10px; margin-bottom: 10px; padding: 3px 10px; border-radius: 15px;">'; echo __('Add items to Order #' . $order_id); echo '</a>'; echo '<a href="#" onclick="toggleOrderDetails(' . $order_id . '); return false;" style="color: #007cba; text-decoration: underline; text-wrap-mode: nowrap;">'; echo __('Show Details'); echo '</a>'; // Hidden details section echo '<div id="order-details-' . $order_id . '" style="display: none; margin-top: 10px;">'; echo '<p><strong>Shipping Method:</strong> ' . $order->get_shipping_method() . ' - ' . wc_price($order->get_shipping_total()) . '</p>'; echo '<p><strong>Payment Method:</strong> ' . $payment_method . '</p>'; echo '<div style="display: flex; gap: 25px;"><p><strong>Shipping Address:</strong><br>' . $order->get_formatted_shipping_address() . '</p>'; echo '<p><strong>Billing Address:</strong><br>' . $order->get_formatted_billing_address() . '</p></div>'; // List of items echo '<p><strong>Items:</strong></p>'; echo '<ul>'; foreach ($order->get_items() as $item) { $product_name = $item->get_name(); $quantity = $item->get_quantity(); echo '<li>' . $product_name . ' x ' . $quantity . '</li>'; } echo '</ul>'; echo '</div>'; // End of order details div echo '</div>'; // End of order block } echo '</div>'; } } } add_action('wp_footer', 'add_toggle_script'); function add_toggle_script() { if (is_checkout()) { echo '<script type="text/javascript"> function toggleOrderDetails(orderId) { var detailsDiv = document.getElementById("order-details-" + orderId); if (detailsDiv.style.display === "none") { detailsDiv.style.display = "block"; } else { detailsDiv.style.display = "none"; } } </script>'; } } add_action('wp_footer', 'add_order_combine_loader_script'); add_action('wp_footer', 'add_order_combine_disable_clicks_script'); function add_order_combine_disable_clicks_script() { if (is_checkout()) { ?> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.combine-order-button').forEach(function(button) { button.addEventListener('click', function (e) { e.preventDefault(); // Create a full-page overlay var overlay = document.createElement('div'); overlay.id = 'disable-clicks-overlay'; overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(255, 255, 255, 0.5)'; overlay.style.zIndex = '10000'; // Append overlay to the body document.body.appendChild(overlay); // Redirect to the combine order URL window.location.href = button.getAttribute('href'); }); }); }); </script> <?php } } add_action('woocommerce_before_checkout_form', 'handle_combine_order'); function handle_combine_order() { // Check if the "combine_order" parameter is present in the URL if (!isset($_GET['combine_order']) || !is_user_logged_in() || empty($_GET['combine_order'])) { return; } $order_id = intval($_GET['combine_order']); $order = wc_get_order($order_id); $current_user_id = get_current_user_id(); // Verify the order exists, belongs to the current user, and meets the requirements if (!$order || $order->get_user_id() !== $current_user_id || !$order->has_status('processing') || $order->get_payment_method() !== 'cod') { wc_add_notice(__('Invalid order or you do not have permission to modify this order.', 'woocommerce'), 'error'); return; } $cart = WC()->cart; if (!$cart || count($cart->get_cart()) === 0) { wc_add_notice(__('Your cart is empty. Please add items to the cart to combine with the existing order.', 'woocommerce'), 'error'); return; } $product_details = []; // For storing product names and quantities for the admin note foreach ($cart->get_cart() as $cart_item) { $product = wc_get_product($cart_item['product_id']); $quantity = $cart_item['quantity']; // Use WooCommerce's reduce_stock method to handle stock reduction if ($product->managing_stock()) { try { $product->reduce_stock($quantity); } catch (Exception $e) { wc_add_notice(sprintf(__('Insufficient stock for product: %s', 'woocommerce'), $product->get_name()), 'error'); return; } } // Add the product to the order if (!$order->add_product($product, $quantity)) { wc_add_notice(__('Failed to add item to order.', 'woocommerce'), 'error'); return; } $product_details[] = $product->get_name() . ' (x' . $quantity . ')'; } // Recalculate totals after adding items $order->calculate_totals(); // Convert product details array into a comma-separated list $product_list = implode(', ', $product_details); // Add an admin note with the added products $order->add_order_note( __('Items have been added to this order from the user\'s new checkout attempt. The total has been updated accordingly. Products added: ' . $product_list, 'woocommerce'), true ); // Temporarily disable the "On Hold" email notification // remove_action('woocommerce_order_status_pending_to_on-hold_notification', ['WC_Email_Customer_On_Hold_Order', 'trigger']); // remove_action('woocommerce_order_status_failed_to_on-hold_notification', ['WC_Email_Customer_On_Hold_Order', 'trigger']); // Set the order status to "On Hold" // $order->update_status('on-hold', __('Order status changed to On Hold after adding items from checkout.', 'woocommerce')); // Re-enable the "On Hold" email notification // add_action('woocommerce_order_status_pending_to_on-hold_notification', ['WC_Email_Customer_On_Hold_Order', 'trigger']); // add_action('woocommerce_order_status_failed_to_on-hold_notification', ['WC_Email_Customer_On_Hold_Order', 'trigger']); // Save the updated order and clear the cart $order->save(); $cart->empty_cart(); // Redirect to the "Thank You" page of the original order wp_safe_redirect($order->get_checkout_order_received_url()); exit; } add_filter( 'woocommerce_register_shop_order_post_statuses', 'bbloomer_register_custom_order_status' ); function bbloomer_register_custom_order_status( $order_statuses ) { // Status must start with "wc-"! $order_statuses['wc-updated'] = array( 'label' => 'Updated', 'public' => false, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, 'label_count' => _n_noop( 'Updated <span class="count">(%s)</span>', 'Updated <span class="count">(%s)</span>', 'woocommerce' ), ); return $order_statuses; } add_filter( 'wc_order_statuses', 'bbloomer_show_custom_order_status_single_order_dropdown' ); function bbloomer_show_custom_order_status_single_order_dropdown( $order_statuses ) { $order_statuses['wc-updated'] = 'Updated'; return $order_statuses; }

Leave a Reply