WooCommerce: consente agli utenti di modificare gli ordini di elaborazione
Pubblicato: 2018-12-18In che modo i clienti di WooCommerce possono modificare un ordine che hanno appena effettuato e pagato? Giuro che ho guardato i risultati dei motori di ricerca e altri posti prima di arrivare alla conclusione che dovevo codificarlo da solo.
Ad esempio, un utente potrebbe voler modificare la data di consegna (se la fornisci nella pagina di pagamento). O forse hanno bisogno di cambiare taglia o prendere una decisione su un determinato prodotto nell'ordine.
Ad ogni modo è scioccante per me questa funzionalità non è in un plug-in – come al solito, se sei interessato a personalizzare questo snippet/plugin per le tue esigenze specifiche, non esitare a contattarci.
Allora, vediamo come si fa!

Snippet (PHP): consenti ai clienti di modificare gli ordini nella pagina del mio account WooCommerce
La prima cosa di cui abbiamo bisogno è mostrare il pulsante "Modifica ordine" solo per l'elaborazione degli ordini . Qui, sto solo approfittando e riutilizzando la funzionalità "Ordina di nuovo" che WooCommerce offre: questo "Ordina di nuovo" sostanzialmente duplica l'ordine dato e riempie il carrello con gli stessi prodotti e meta.
Se ottieni il mio punto, "Modifica ordine" equivale a duplicare l'ordine che desideri modificare, effettuare un nuovo ordine ed eliminare quello precedente . Almeno questo è come lo vedo io ed è decisamente più facile in questo modo.
Per mostrare il pulsante "Modifica ordine" per l'elaborazione degli ordini, dobbiamo sbloccare il pulsante "Ordina di nuovo" (filtro (filtro "woocommerce_valid_order_statuses_for_order_again"). Per impostazione predefinita, questo viene visualizzato solo per gli ordini completati: anche noi abbiamo bisogno dell'elaborazione (parte 1).
Ora posso stampare il pulsante "Modifica ordine" con il filtro "woocommerce_my_account_my_orders_actions". Come puoi vedere, "add_query_arg" deve avere "order_again" in modo che facendo clic sul pulsante si attivi una funzione di nuovo ordine, e inoltre aggiungo un secondo "add_query_arg" uguale a "edit_order" in modo da sapere che il pulsante Modifica ordine è stato cliccato e non l'Ordine di nuovo. Il pulsante "nome" cambia in "Modifica ordine" (parte 2).
Ottimo – ora il pulsante verrà visualizzato in Il mio account > Ordini per l'elaborazione degli ordini, e al clic verrà reindirizzato all'URL del carrello che conterrà un parametro (e il carrello verrà riempito con gli stessi prodotti, grazie al parametro "order_again" ). Ora posso semplicemente "ascoltarlo" e vedere se il pulsante è stato cliccato durante "woocommerce_cart_loaded_from_session". Posso usare "$_GET" per vedere se l'URL contiene parametri e, in caso affermativo, aggiungo l'ID dell'ordine modificato alla sessione del carrello (parte 3).
Ora passo alle parti 4 e 5: voglio mostrare a un carrello l'avviso che il carrello è stato riempito con gli stessi prodotti dell'ordine precedente, e anche che è stato applicato un "credito" al carrello corrente sotto forma di sconto (" add_fee”) – sì, è uno sconto pari allo stesso valore del totale dell'ordine pagato in precedenza.
Aggiornamento gennaio 2019: tieni presente che add_fee() non funziona bene quando si utilizzano importi negativi E hai le tasse abilitate. In questo caso dovresti trovare un'alternativa.
E poi passiamo alla sezione finale, parte 6: se il cliente effettua l'ordine, dobbiamo chiaramente annullare l'ordine "modificato" e mostrare un avviso nella pagina di amministrazione dell'ordine di entrambi gli ordini, incluso un collegamento all'ordine pertinente ( rispettivamente cancellato o nuovo). Per questo, utilizzo la funzione "aggiungi_ordine_nota".

Bene, una lunga spiegazione, ma spero che questo sia utile
/**
* @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 );
}
}