WooCommerce: Kullanıcıların İşleme Siparişlerini Düzenlemesine İzin Verin

Yayınlanan: 2018-12-18

WooCommerce müşterileri yeni verdikleri ve ödemesini yaptıkları bir siparişi nasıl düzenleyebilir? Yemin ederim ki, bunu kendim kodlamam gerektiği sonucuna varmadan önce arama motoru sonuçlarına ve diğer yerlere baktım.

Örneğin, bir kullanıcı teslimat tarihini değiştirmek isteyebilir (bunu ödeme sayfasında belirtirseniz). Ya da belki bedenlerini değiştirmeleri ya da siparişteki belirli bir ürün hakkında karar vermeleri gerekiyor.

Her iki durumda da, bu işlevin bir eklentide olmaması beni şok ediyor - her zamanki gibi bu snippet'i/eklentiyi özel ihtiyaçlarınız için özelleştirmekle ilgileniyorsanız, iletişime geçmekten çekinmeyin.

Öyleyse, nasıl yapıldığını görelim!

Yalnızca Siparişlerin İşlenmesi için bir "Siparişi Düzenle" düğmesinin görüntülenmesi – WooCommerce

Snippet (PHP): Müşterilerin Siparişleri Düzenlemesine İzin Ver @ WooCommerce Hesabım Sayfası

İhtiyacımız olan ilk şey, yalnızca İşleme Siparişleri için “Siparişi Düzenle” düğmesini göstermektir . Burada, WooCommerce'in sunduğu “Yeniden Sipariş Et” işlevselliğinden yararlanıyorum ve yeniden kullanıyorum – bu “Yeniden Sipariş Et” temelde verilen siparişi çoğaltır ve Sepeti aynı ürünler ve meta ile doldurur.

Demek istediğim, "Siparişi Düzenle", düzenlemek istediğiniz siparişi çoğaltmak, yeni bir sipariş vermek ve bir öncekini silmekle aynı şeydir . En azından ben böyle görüyorum ve bu şekilde kesinlikle daha kolay geliyor.

Siparişleri işlemek için “Siparişi Düzenle” düğmesini göstermek için “Yeniden Sipariş Ver” düğmesinin kilidini açmamız gerekiyor (“woocommerce_valid_order_statuses_for_order_again” filtresi). Varsayılan olarak bu yalnızca tamamlanmış siparişler için görüntülenir - bizim de işleme ihtiyacımız var (bölüm 1).

Artık “woocommerce_my_account_my_orders_actions” filtresi ile “Siparişi Düzenle” butonunu yazdırabilirim. Gördüğünüz gibi, “add_query_arg”ın “order_again” olması gerekir, böylece butona tıklamak tekrar bir sipariş fonksiyonunu tetikler ve ayrıca “edit_order”a eşit ikinci bir “add_query_arg” ekliyorum, böylece Edit Order butonunun tıklandığını anlarım ve Değil Sipariş Tekrar. “Ad” düğmesi “Siparişi Düzenle” olarak değişir (bölüm 2).

Harika – şimdi düğme Hesabım > Siparişleri işlemek için Siparişler altında görünecek ve bu tıklandığında bir parametre içeren bir Sepet URL'sine yönlendirilecek (ve "order_again" parametresi sayesinde Sepet aynı ürünlerle doldurulacak) ). Artık bunu basitçe "dinleyebilirim" ve "woocommerce_cart_loaded_from_session" sırasında düğmenin tıklanıp tıklanmadığını görebilirim. URL'nin parametre içerip içermediğini görmek için “$_GET” kullanabilirim – ve evetse, düzenlenen sipariş kimliğini sepet oturumuna eklerim (bölüm 3).

Şimdi 4. ve 5. bölümlere geçiyorum: Sepetin önceki siparişin aynı ürünleriyle doldurulduğunu ve ayrıca mevcut sepete indirim şeklinde bir "kredi" uygulandığını bir Sepet bildirimi göstermek istiyorum (“ add_fee”) – evet, daha önce ödenen sipariş toplamının aynı değerine eşit bir indirim.

Ocak 2019 Güncellemesi: eksi tutarları kullanırken add_fee() işlevinin iyi çalışmadığını VE vergileri etkinleştirdiğinizi lütfen unutmayın. Bu durumda bir alternatif bulmanız gerekir.

Ardından, son bölüm olan 6. bölüme geçiyoruz: müşteri siparişi verirse , "düzenlenmiş" siparişi iptal etmemiz ve her iki siparişin sipariş yöneticisi sayfasında ilgili siparişe bir bağlantı da dahil olmak üzere bir bildirim göstermemiz gerekir ( sırasıyla iptal edilmiş veya yeni). Bunun için “add_order_note” fonksiyonunu kullanıyorum.

Uzun bir açıklama ama umarım işine yarar

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