WooCommerce: ユーザーが処理注文を編集できるようにする
公開: 2018-12-18WooCommerce の顧客は、発注して支払ったばかりの注文をどのように編集できますか? これを自分でコーディングする必要があるという結論に達する前に、検索エンジンの結果やその他の場所を調べたことを誓います。
たとえば、ユーザーが配達日を変更したい場合があります (チェックアウト ページで指定した場合)。 または、サイズを変更する必要があるか、注文の特定の製品について決心する必要があるかもしれません。
いずれにせよ、この機能がプラグインに含まれていないのは衝撃的です。いつものように、特定のニーズに合わせてこのスニペット/プラグインをカスタマイズすることに興味がある場合は、お気軽にお問い合わせください.
それでは、それがどのように行われるか見てみましょう!
スニペット (PHP): 顧客が WooCommerce マイ アカウント ページで注文を編集できるようにする
最初に、処理中の注文のみに「注文の編集」ボタンを表示する必要があります。 ここでは、WooCommerce が提供する「再注文」機能を利用して再利用しています。この「再注文」は、基本的に指定された注文を複製し、同じ製品とメタでカートを満たします。
要するに、「注文の編集」とは、編集したい注文を複製し、新しい注文を出し、前の注文を削除することと同じです。 少なくともこれは私が見ている方法であり、この方法で間違いなく簡単になります。
注文を処理するための [Edit Order] ボタンを表示するには、[Order Again] ボタン (「woocommerce_valid_order_statuses_for_order_again」フィルター) のロックを解除する必要があります。 デフォルトでは、これは完了した注文に対してのみ表示されます。処理も必要です (パート 1)。
これで、「woocommerce_my_account_my_orders_actions」フィルターを使用して「Edit Order」ボタンを印刷できます。 ご覧のとおり、「add_query_arg」には「order_again」が必要です。これにより、ボタンをクリックすると再度注文機能がトリガーされます。また、「edit_order」に等しい 2 番目の「add_query_arg」を追加して、[Edit Order] ボタンがクリックされたことを認識できるようにします。オーダーアゲインではありません。 ボタン「name」が「Edit Order」に変わります (その 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 );
}
}