Permitir a tus clientes repetir pedidos de WooCommerce

    Botón que añade todos los productos de un pedido de nuevo a la cesta para volver a comprarlos.

    /* Boton de modificar pedido */
    // 1. Permitimos el estado de pedir otra vez para pedidos en proceso
    add_filter('woocommerce_valid_order_statuses_for_order_again', 'nwp_estado_pedir_otra_vez');
    
    function nwp_estado_pedir_otra_vez($statuses) {
        $statuses[] = 'processing';
        return $statuses;
    }
    // 2. Agregamos las acciones del pedido a la cuenta
    add_filter('woocommerce_my_account_my_orders_actions', 'nwp_acciones_pedido_cuenta', 50, 2);
    
    function nwp_acciones_pedido_cuenta($actions, $order) {
        if ($order - > has_status('processing')) {
            $actions['edit-order'] = array(
                'url' => wp_nonce_url(add_query_arg(array('order_again' => $order - > get_id(), 'edit_order' => $order - > get_id())), 'woocommerce-order_again'),
                'name' => __('Modificar pedido', 'woocommerce')
            );
        }
        return $actions;
    }
    // 3. Detectar la accion del pedido modificado
    add_action('woocommerce_cart_loaded_from_session', 'nwp_detectar_pedido_modificado');
    
    function nwp_detectar_pedido_modificado($cart) {
        if (isset($_GET['edit_order'], $_GET['_wpnonce']) && is_user_logged_in() && wp_verify_nonce(wp_unslash($_GET['_wpnonce']), 'woocommerce-order_again')) WC() - > session - > set('edit_order', absint($_GET['edit_order']));
    }
    // 4. Mostrar aviso en el carrito de que es un pedido modificado
    add_action('woocommerce_before_cart', 'nwp_mostrar_que_es_pedido_modificado');
    
    function nwp_mostrar_que_es_pedido_modificado() {
        if (!is_cart()) return;
        $edited = WC() - > session - > get('edit_order');
        if (!empty($edited)) {
            $order = new WC_Order($edited);
            $credit = $order - > get_total();
            wc_print_notice('Tienes un crédito de '.wc_price($credit).
                ' aplicado al pedido. Añade productos o cambia los detalles que quieras, como fecha de entrega y finaliza el pedido.', 'notice');
        }
    }
    // 5. Calcular nuevo total del pedido modificado
    add_action('woocommerce_cart_calculate_fees', 'nwp_calcular_nuevo_total', 20, 1);
    
    function nwp_calcular_nuevo_total($cart) {
        if (is_admin() && !defined('DOING_AJAX')) return;
        $edited = WC() - > session - > get('edit_order');
        if (!empty($edited)) {
            $order = new WC_Order($edited);
            $credit = -1 * $order - > get_total();
            $cart - > add_fee('Crédito', $credit);
        }
    }
    // 6. Guardar pedido si se ha modificado
    add_action('woocommerce_checkout_update_order_meta', 'nwp_guardar_pedido_modificado');
    
    function nwp_guardar_pedido_modificado($order_id) {
        $edited = WC() - > session - > get('edit_order');
        if (!empty($edited)) {
            // Actualizamos este nuevo pedido
            update_post_meta($order_id, '_edit_order', $edited);
            $neworder = new WC_Order($order_id);
            $oldorder_edit = get_edit_post_link($edited);
            $neworder - > add_order_note('Pedido realizado a partir de una modificación. Número del pedido anterior: <a href="'.$oldorder_edit.
                '">'.$edited.
                '</a>');
            // cancel previous order
            $oldorder = new WC_Order($edited);
            $neworder_edit = get_edit_post_link($order_id);
            $oldorder - > update_status('cancelled', 'Pedido cancelado al haber una modificación del mismo. Número del nuevo pedido: <a href="'.$neworder_edit.
                '">'.$order_id.
                '</a> -');
            WC() - > session - > set('edit_order', null);
        }
    }