WooCommerce: السماح للمستخدمين بتعديل أوامر المعالجة
نشرت: 2018-12-18كيف يمكن لعملاء WooCommerce تعديل طلب قاموا بتقديمه ودفعوا مقابله للتو؟ أقسم أنني بحثت في نتائج محرك البحث وأماكن أخرى قبل أن أصل إلى الاستنتاج الذي كنت بحاجة إليه لترميز هذا بنفسي.
على سبيل المثال ، قد يرغب المستخدم في تغيير تاريخ التسليم (إذا قمت بتوفير ذلك في صفحة الخروج). أو ربما يحتاجون إلى تغيير الحجم ، أو اتخاذ قرار بشأن منتج معين بالترتيب.
في كلتا الحالتين ، من المثير للصدمة بالنسبة لي أن هذه الوظيفة ليست في مكون إضافي - كالمعتاد إذا كنت مهتمًا بتخصيص هذا المقتطف / المكون الإضافي لاحتياجاتك الخاصة ، فلا تتردد في الاتصال.
لذا ، دعنا نرى كيف يتم ذلك!
Snippet (PHP): السماح للعملاء بتحرير الطلبات @ صفحة حسابي على WooCommerce
أول شيء نحتاجه هو إظهار زر "تعديل الأمر" لمعالجة الطلبات فقط . هنا ، أنا فقط أستفيد وأعيد استخدام وظيفة "Order Again" التي تقدمها WooCommerce - هذا "الطلب مرة أخرى" يكرر الطلب المحدد ويملأ سلة التسوق بنفس المنتجات والميتا.
إذا حصلت على وجهة نظري ، فإن "تعديل الطلب" هو نفس تكرار الأمر الذي تريد تعديله ، وتقديم طلب جديد وحذف الطلب السابق . على الأقل هذا ما أراه وهو بالتأكيد أسهل بهذه الطريقة.
لإظهار زر "تعديل الطلب" لمعالجة الطلبات ، نحتاج إلى إلغاء قفل زر "الطلب مرة أخرى" (مرشح "woocommerce_valid_order_statuses_for_order_again"). بشكل افتراضي ، يتم عرض هذا فقط للطلبات المكتملة - نحتاج إلى المعالجة أيضًا (الجزء 1).
يمكنني الآن طباعة زر "تعديل الطلب" باستخدام مرشح "woocommerce_my_account_my_orders_actions". كما ترى ، يجب أن يحتوي "add_query_arg" على "order_again" بحيث يؤدي النقر فوق الزر إلى تشغيل وظيفة الطلب مرة أخرى ، وأضيف أيضًا "add_query_arg" ثانيًا يساوي "edit_order" حتى أعرف أن زر تحرير الأمر قد تم النقر عليه و ليس الأمر مرة أخرى. يتغير زر "الاسم" إلى "تعديل الأمر" (الجزء 2).
رائع - سيظهر الزر الآن ضمن حسابي> طلبات معالجة الطلبات ، وعند النقر فوق هذا سيتم إعادة التوجيه إلى عنوان URL لعربة التسوق الذي سيحتوي على معلمة (وسيتم ملء سلة التسوق بالمنتجات نفسها ، وذلك بفضل المعلمة "order_again" ). يمكنني الآن ببساطة "الاستماع" إلى هذا ومعرفة ما إذا كان الزر قد تم النقر عليه أثناء "woocommerce_cart_loaded_from_session". يمكنني استخدام "$ _GET" لمعرفة ما إذا كان عنوان URL يحتوي على معلمات أم لا - وإذا كانت الإجابة بنعم ، فقم بإضافة معرف الطلب المعدل إلى جلسة سلة التسوق (الجزء 3).
أنتقل الآن إلى الجزأين 4 و 5: أريد إظهار إشعار عربة التسوق يفيد بأن عربة التسوق قد تم ملؤها بنفس منتجات الطلب السابق ، وأيضًا أنه تم تطبيق "ائتمان" على عربة التسوق الحالية في شكل خصم (" add_fee ”) - نعم ، إنه خصم يساوي نفس قيمة إجمالي الطلب الذي تم دفعه مسبقًا.
تحديث يناير 2019: يرجى ملاحظة أن 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 );
}
}