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!

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 una respuesta