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;
}