WooCommerce: permiteți utilizatorilor să editeze comenzile de procesare
Publicat: 2018-12-18Cum pot clienții WooCommerce să editeze o comandă pe care tocmai au plasat-o și pentru care au plătit-o? Jur că m-am uitat la rezultatele motoarelor de căutare și în alte locuri înainte de a ajunge la concluzia că aveam nevoie să codific asta.
De exemplu, un utilizator ar putea dori să modifice data de livrare (dacă furnizați aceasta pe pagina de finalizare a comenzii). Sau poate că trebuie să schimbe dimensiunea sau să se hotărască despre un anumit produs din comandă.
În orice caz, este șocant pentru mine, această funcționalitate nu este într-un plugin - ca de obicei, dacă sunteți interesat să personalizați acest fragment/plugin pentru nevoile dvs. specifice, nu ezitați să luați legătura.
Deci, să vedem cum se face!
Fragment (PHP): Permiteți clienților să editeze comenzi pe pagina contului meu WooCommerce
Primul lucru de care avem nevoie este să afișăm butonul „Editați comanda” numai pentru procesarea comenzilor . Aici, doar profit și reutilizați funcționalitatea „Comandă din nou” pe care o oferă WooCommerce – acest „Comandă din nou” practic dublează comanda dată și umple coșul cu aceleași produse și meta.
Dacă înțelegeți punctul meu de vedere, „Editați comanda” este același cu duplicarea comenzii pe care doriți să o editați, plasarea unei noi comenzi și ștergerea celei anterioare . Cel puțin așa văd eu și este cu siguranță mai ușor în acest fel.
Pentru a afișa butonul „Editați comanda” pentru procesarea comenzilor, trebuie să deblocăm butonul „Comanda din nou” (filtrul „woocommerce_valid_order_statuses_for_order_again”). În mod implicit, se afișează numai pentru comenzile finalizate – avem nevoie și de procesare (partea 1).
Acum pot imprima butonul „Editați comanda” cu filtrul „woocommerce_my_account_my_orders_actions”. După cum puteți vedea, „add_query_arg” trebuie să aibă „order_again”, astfel încât făcând clic pe butonul să declanșeze o funcție de comandă din nou, și, de asemenea, adaug un al doilea „add_query_arg” egal cu „edit_order”, astfel încât să știu că butonul Edit Order a fost apăsat și nu Ordinul Din nou. Butonul „nume” se schimbă în „Editare comandă” (partea 2).
Grozav – acum butonul va apărea sub Contul meu > Comenzi pentru procesarea comenzilor, iar la clic pe acesta va fi redirecționat către o adresă URL a coșului care va conține un parametru (și coșul va fi completat cu aceleași produse, datorită parametrului „order_again” ). Acum pot pur și simplu să „ascult” acest lucru și să văd dacă butonul a fost apăsat în timpul „woocommerce_cart_loaded_from_session”. Pot folosi „$_GET” pentru a vedea dacă adresa URL conține parametri – și dacă da, adaug ID-ul comenzii editat la sesiunea de coș (partea 3).
Acum trec la părțile 4 și 5: vreau să arăt o notificare Coș că coșul a fost umplut cu aceleași produse din comanda anterioară și, de asemenea, că s-a aplicat un „credit” coșului curent sub formă de reducere (“ add_fee”) – da, este o reducere care este egală cu aceeași valoare a totalului comenzii plătită anterior.
Actualizare ianuarie 2019: rețineți că add_fee() nu funcționează bine atunci când utilizați sume negative ȘI aveți taxele activate. În acest caz, ar trebui să găsiți o alternativă.
Și apoi trecem la secțiunea finală, partea 6: dacă clientul plasează comanda, trebuie în mod clar să anulăm comanda „editată” și să afișăm o notificare în pagina de administrare a comenzilor a ambelor comenzi, inclusiv un link către comanda relevantă ( anulat sau, respectiv, nou). Pentru aceasta, folosesc funcția „add_order_note”.
Ei bine, o explicație lungă, dar sper că aceasta este de ajutor
/**
* @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' );
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' ) ) {
$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' => __( 'Edit Order', 'woocommerce' )
);
}
return $actions;
}
// ----------------
// 3. Detect Edit Order Action and Store in Session
add_action( 'woocommerce_cart_loaded_from_session', 'bbloomer_detect_edit_order' );
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' ) ) 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' );
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 ' . 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' );
}
}
// ----------------
// 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' ) ) 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' );
function bbloomer_save_edit_order( $order_id ) {
$edited = WC()->session->get( 'edit_order' );
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="' . $oldorder_edit . '">' . $edited . '</a>' );
// 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="' . $neworder_edit . '">' . $order_id . '</a> -' );
WC()->session->set( 'edit_order', null );
}
}