WooCommerce: permitir a los usuarios editar órdenes de procesamiento

¿Cómo pueden los clientes de WooCommerce editar un pedido que acaban de realizar y pagar? Juro que miré los resultados del motor de búsqueda y otros lugares antes de llegar a la conclusión de que necesitaba codificar esto yo mismo.

Por ejemplo, es posible que un usuario desee cambiar la fecha de entrega (si la proporciona en la página de pago). O tal vez necesiten cambiar de talla, o decidirse por un producto determinado en el pedido.

De cualquier manera, me sorprende que esta funcionalidad no esté en un complemento; como de costumbre, si está interesado en personalizar este fragmento/complemento para sus necesidades específicas, no dude en ponerse en contacto.

Entonces, ¡veamos cómo se hace!

Mostrar un botón «Editar pedido» solo para procesamiento de pedidos – WooCommerce

Fragmento (PHP): permitir que los clientes editen pedidos en la página Mi cuenta de WooCommerce

Lo primero que necesitamos es mostrar el botón “Editar Orden” solo para Procesar Órdenes . Aquí, solo estoy aprovechando y reutilizando la funcionalidad «Pedir de nuevo» que ofrece WooCommerce: este «Pedido de nuevo» básicamente duplica el pedido dado y llena el carrito con los mismos productos y meta.

Si entiende mi punto, «Editar pedido» es lo mismo que duplicar el pedido que desea editar, realizar un nuevo pedido y eliminar el anterior . Al menos así es como yo lo veo y es definitivamente más fácil de esta manera.

Para mostrar el botón «Editar pedido» para procesar pedidos, debemos desbloquear el botón «Pedir de nuevo» (filtro «woocommerce_valid_order_statuses_for_order_again»). De forma predeterminada, esto solo se muestra para los pedidos completados; también necesitamos procesamiento (parte 1).

Ahora puedo imprimir el botón «Editar pedido» con el filtro «woocommerce_my_account_my_orders_actions». Como puede ver, «add_query_arg» debe tener «order_again» para que al hacer clic en el botón se active una función de orden nuevamente, y también agrego un segundo «add_query_arg» igual a «edit_order» para saber que se hizo clic en el botón Editar orden y no la orden otra vez. El botón «nombre» cambia a «Editar orden» (parte 2).

Genial: ahora el botón se mostrará en Mi cuenta > Pedidos para procesar pedidos y, al hacer clic, se redirigirá a una URL del carrito que contendrá un parámetro (y el carrito se completará con los mismos productos, gracias al parámetro «order_again» ). Ahora puedo simplemente «escuchar» esto y ver si se hizo clic en el botón durante «woocommerce_cart_loaded_from_session». Puedo usar «$_GET» para ver si la URL contiene parámetros y, en caso afirmativo, agrego el ID de pedido editado a la sesión del carrito (parte 3).

Ahora me muevo a las partes 4 y 5: quiero mostrar un aviso de carrito que se ha llenado con los mismos productos del pedido anterior, y también que se ha aplicado un «crédito» al carrito actual en forma de descuento (» add_fee”) – sí, es un descuento que equivale al mismo valor del total del pedido pagado anteriormente.

Actualización de enero de 2019: tenga en cuenta que add_fee() no funciona bien cuando se usan montos negativos Y tiene los impuestos habilitados. En este caso, tendrías que buscar una alternativa.

Y luego pasamos a la sección final, parte 6: si el cliente realiza el pedido, claramente debemos cancelar el pedido «editado» y mostrar un aviso en la página de administración de pedidos de ambos pedidos, incluido un enlace al pedido relevante ( cancelado o nuevo, respectivamente). Para esto, uso la función «add_order_note».

Bueno, una larga explicación, pero espero que esto sea útil.

/**
 * @snippet       Edit Order Functionality @ WooCommerce My Account Page
 * @how-to        Get CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=91893
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 4.1
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
  
// ----------------
// 1. Allow Order Again for Processing Status
  
add_filter( 'woocommerce_valid_order_statuses_for_order_again', 'bbloomer_order_again_statuses'%20);
  
function bbloomer_order_again_statuses( $statuses ) {
    $statuses[] = 'processing';
    return $statuses;
}
  
// ----------------
// 2. Add Order Actions @ My Account
  
add_filter( 'woocommerce_my_account_my_orders_actions', 'bbloomer_add_edit_order_my_account_orders_actions', 50, 2 );
  
function bbloomer_add_edit_order_my_account_orders_actions( $actions, $order ) {
    if ( $order->has_status( 'processing'%20) ) {
        $actions['edit-order'] = array(
            'url'  => wp_nonce_url( add_query_arg( array( 'order_again'%20=> $order->get_id(), 'edit_order'%20=> $order->get_id() ) ), 'woocommerce-order_again'%20),
            'name'%20=> __( 'Edit Order', 'woocommerce'%20)
        );
    }
    return $actions;
}
  
// ----------------
// 3. Detect Edit Order Action and Store in Session
  
add_action( 'woocommerce_cart_loaded_from_session', 'bbloomer_detect_edit_order'%20);
             
function bbloomer_detect_edit_order( $cart ) {
    if ( isset( $_GET['edit_order'], $_GET['_wpnonce'] ) && is_user_logged_in() && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'woocommerce-order_again'%20) ) WC()->session->set( 'edit_order', absint( $_GET['edit_order'] ) );
}
  
// ----------------
// 4. Display Cart Notice re: Edited Order
  
add_action( 'woocommerce_before_cart', 'bbloomer_show_me_session'%20);
  
function bbloomer_show_me_session() {
    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( 'A credit of '%20. wc_price($credit) . ' has been applied to this new order. Feel free to add products to it or change other details such as delivery date.', 'notice'%20);
    }
}
  
// ----------------
// 5. Calculate New Total if Edited Order
   
add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_use_edit_order_total', 20, 1 );
   
function bbloomer_use_edit_order_total( $cart ) {
    
  if ( is_admin() && ! defined( 'DOING_AJAX'%20) ) return;
     
  $edited = WC()->session->get('edit_order');
  if ( ! empty( $edited ) ) {
      $order = new WC_Order( $edited );
      $credit = -1 * $order->get_total();
      $cart->add_fee( 'Credit', $credit );
  }
    
}
  
// ----------------
// 6. Save Order Action if New Order is Placed
  
add_action( 'woocommerce_checkout_update_order_meta', 'bbloomer_save_edit_order'%20);
   
function bbloomer_save_edit_order( $order_id ) {
    $edited = WC()->session->get( 'edit_order'%20);
    if ( ! empty( $edited ) ) {
        // update this new order
        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( 'Order placed after editing. Old order number: <a href="'%20. $oldorder_edit . '">'%20. $edited . '</a>'%20);
        // cancel previous order
        $oldorder = new WC_Order( $edited );
        $neworder_edit = get_edit_post_link( $order_id );
        $oldorder->update_status( 'cancelled', 'Order cancelled after editing. New order number: <a href="'%20. $neworder_edit . '">'%20. $order_id . '</a> -'%20);
        WC()->session->set( 'edit_order', null );
    }
}

Deja un comentario