WooCommerce: 사용자가 처리 주문을 편집할 수 있도록 허용

게시 됨: 2018-12-18

WooCommerce 고객은 방금 주문하고 결제한 주문을 어떻게 편집할 수 있습니까? 나는 이것을 직접 코딩해야 한다는 결론에 도달하기 전에 검색 엔진 결과와 다른 곳을 봤다고 맹세합니다.

예를 들어, 사용자가 배송 날짜를 변경하기를 원할 수 있습니다(체크아웃 페이지에서 제공한 경우). 또는 크기를 변경하거나 주문에 지정된 제품에 대해 결정해야 할 수도 있습니다.

어느 쪽이든 이 기능이 플러그인에 없다는 것이 저에게는 충격적입니다. 평소와 같이 특정 요구에 맞게 이 스니펫/플러그인을 사용자 정의하는 데 관심이 있다면 언제든지 연락하십시오.

자, 어떻게 되었는지 봅시다!

주문 처리에만 "주문 편집" 버튼 표시 – WooCommerce

스니펫(PHP): 고객이 주문을 편집할 수 있도록 허용 @ WooCommerce 내 계정 페이지

가장 먼저 필요한 것은 처리 주문에 대해서만 "주문 편집" 버튼을 표시하는 것 입니다. 여기에서는 WooCommerce가 제공하는 "다시 주문" 기능을 활용하고 재사용하고 있습니다. 이 "다시 주문"은 기본적으로 지정된 주문을 복제하고 동일한 제품 및 메타로 장바구니를 채웁니다.

제 요점을 알면 "주문 편집"은 편집하려는 주문을 복제하고 새 주문을하고 이전 주문을 삭제하는 것과 같습니다. 적어도 이것이 내가 보는 방식이며 이러한 방식으로 확실히 더 쉽습니다.

주문 처리를 위한 "주문 편집" 버튼을 표시하려면 "다시 주문" 버튼("woocommerce_valid_order_statuses_for_order_again" 필터)을 잠금 해제해야 합니다. 기본적으로 완료된 주문에만 표시됩니다. 처리도 필요합니다(1부).

이제 "woocommerce_my_account_my_orders_actions" 필터로 "주문 편집" 버튼을 인쇄할 수 있습니다. 보시다시피 "add_query_arg"에는 "order_again"이 있어야 버튼을 클릭하면 다시 주문 기능이 트리거되고, "edit_order"와 동일한 두 번째 "add_query_arg"를 추가하여 주문 편집 버튼이 클릭되었음을 알 수 있습니다. 오더 어게인이 아닙니다. "이름" 버튼이 "주문 편집"(파트 2)으로 변경됩니다.

좋습니다. 이제 버튼이 내 계정 > 주문 처리 아래에 표시되며, 클릭하면 매개변수가 포함된 장바구니 URL로 리디렉션됩니다("order_again" 매개변수 덕분에 장바구니는 동일한 제품으로 채워집니다. ). 이제 간단히 "듣고" 버튼이 "woocommerce_cart_loaded_from_session" 동안 클릭되었는지 확인할 수 있습니다. "$_GET"을 사용하여 URL에 매개변수가 포함되어 있는지 확인할 수 있습니다. 그렇다면 편집된 주문 ID를 장바구니 세션에 추가합니다(3부).

이제 파트 4와 5로 이동 합니다. 장바구니에 이전 주문의 동일한 제품이 채워져 있고 할인 형태로 현재 장바구니에 "크레딧"이 적용되었다는 알림을 장바구니에 표시하고 싶습니다 (" add_fee”) – 예, 이전에 지불한 주문 총액과 동일한 금액의 할인입니다.

2019년 1월 업데이트: 음수 금액을 사용하고 세금을 활성화하면 add_fee()가 제대로 작동하지 않습니다. 이 경우 대안을 찾아야 합니다.

그런 다음 마지막 섹션인 파트 6으로 이동합니다. 고객이 주문 하면 "편집된" 주문을 취소 하고 관련 주문에 대한 링크를 포함하여 두 주문의 주문 관리 페이지에 알림을 표시해야 합니다( 취소 또는 신규). 이를 위해 "add_order_note" 기능을 사용합니다.

글쎄요, 설명이 길지만 도움이 되었으면 합니다.

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