WooCommerce: Izinkan Pengguna Mengedit Pesanan Pemrosesan

Diterbitkan: 2018-12-18

Bagaimana pelanggan WooCommerce dapat mengedit pesanan yang baru saja mereka buat dan bayar? Saya bersumpah saya melihat hasil mesin pencari dan tempat-tempat lain sebelum sampai pada kesimpulan bahwa saya perlu membuat kode ini sendiri.

Misalnya, pengguna mungkin ingin mengubah tanggal pengiriman (jika Anda memberikan ini di halaman checkout). Atau mungkin mereka perlu mengubah ukuran, atau mengambil keputusan tentang produk tertentu dalam pesanan.

Either way itu mengejutkan saya fungsi ini tidak ada dalam plugin – seperti biasa jika Anda tertarik untuk menyesuaikan potongan/plugin ini untuk kebutuhan spesifik Anda, jangan ragu untuk menghubungi.

Jadi, mari kita lihat bagaimana hal itu dilakukan!

Menampilkan tombol “Edit Pesanan” hanya untuk Memproses Pesanan – WooCommerce

Cuplikan (PHP): Izinkan Pelanggan untuk Mengedit Pesanan @ WooCommerce Halaman Akun Saya

Hal pertama yang kita perlukan adalah menampilkan tombol “Edit Pesanan” untuk Memproses Pesanan saja . Di sini, saya hanya mengambil keuntungan dan menggunakan kembali fungsi “Pesan Lagi” yang ditawarkan WooCommerce – “Pesan Lagi” ini pada dasarnya menduplikasi pesanan yang diberikan dan mengisi Keranjang dengan produk dan meta yang sama.

Jika Anda mengerti maksud saya, "Edit Pesanan" sama dengan menduplikasi pesanan yang ingin Anda edit, menempatkan pesanan baru dan menghapus yang sebelumnya . Setidaknya beginilah cara saya melihatnya dan itu pasti lebih mudah dengan cara ini.

Untuk menampilkan tombol "Edit Pesanan" untuk memproses pesanan, kita perlu membuka kunci tombol "Pesan Lagi" (filter "woocommerce_valid_order_statuses_for_order_again"). Secara default, ini hanya ditampilkan untuk pesanan yang sudah selesai – kami juga membutuhkan pemrosesan (bagian 1).

Sekarang saya dapat mencetak tombol “Edit Pesanan” dengan filter “woocommerce_my_account_my_orders_actions”. Seperti yang Anda lihat, "add_query_arg" harus memiliki "order_again" sehingga mengklik tombol memicu fungsi order lagi, dan juga saya menambahkan "add_query_arg" kedua sama dengan "edit_order" sehingga saya tahu tombol Edit Order diklik dan bukan Orde Lagi. Tombol "nama" berubah menjadi "Edit Pesanan" (bagian 2).

Bagus – sekarang tombol akan muncul di bawah Akun Saya > Pesanan untuk memproses pesanan, dan saat diklik ini akan dialihkan ke URL Keranjang yang akan berisi parameter (dan Keranjang akan diisi dengan produk yang sama, berkat parameter “order_again” ). Saya sekarang dapat dengan mudah "mendengarkan" ini dan melihat apakah tombol diklik selama "woocommerce_cart_loaded_from_session". Saya dapat menggunakan “$_GET” untuk melihat apakah URL berisi parameter – dan jika ya, saya menambahkan ID pesanan yang telah diedit ke sesi keranjang (bagian 3).

Sekarang saya pindah ke bagian 4 dan 5: Saya ingin menunjukkan keranjang pemberitahuan bahwa keranjang telah diisi dengan produk yang sama dari pesanan sebelumnya, dan juga bahwa "kredit" telah diterapkan ke keranjang saat ini dalam bentuk diskon (“ add_fee”) – ya, itu adalah diskon yang sama dengan nilai yang sama dari total pesanan yang dibayarkan sebelumnya.

Perbarui Januari 2019: harap perhatikan bahwa add_fee() tidak berfungsi dengan baik saat menggunakan jumlah negatif DAN pajak Anda diaktifkan. Dalam hal ini Anda perlu mencari alternatif.

Dan kemudian kita pindah ke bagian terakhir, bagian 6: jika pelanggan memesan, kita jelas perlu membatalkan pesanan yang "diedit" dan menunjukkan pemberitahuan di halaman admin pesanan dari kedua pesanan, termasuk tautan ke pesanan yang relevan ( dibatalkan atau baru, masing-masing). Untuk ini, saya menggunakan fungsi “add_order_note”.

Yah, penjelasannya panjang tapi semoga bermanfaat

/**
 * @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 );
    }
}