【问题标题】:Change Woocommerce booking status on Custom Order Status change在自定义订单状态更改时更改 Woocommerce 预订状态
【发布时间】:2018-08-30 03:27:09
【问题描述】:

我有一些自定义订单状态(使用 WooCommerce 订单状态管理器制作)。但是当我使用自定义付费状态时,预订状态不会更新为“付费”。我从各种参考资料中拼凑了一些代码,但这会导致致命错误。或者我可能遗漏了一些自定义状态应该在没有额外代码的情况下更新预订付款状态的东西?

我的代码:

add_action('woocommerce_order_status_pool-payment-rec','auto_change_booking_status_to_paid', 10, 1);
function auto_change_booking_status_to_paid($booking_id) {
    $booking = new WC_Booking( $booking_id );
    $order_id = $booking->get_order_id();
    $booking->update_status('paid', 'order_note');
    exit;
}

错误:

[20-Mar-2018 23:32:05 UTC] PHP Fatal error:  Uncaught Exception: Invalid booking. in /home/ahbc/public_html/wp-content/plugins/woocommerce-bookings/includes/data-stores/class-wc-booking-data-store.php:83
Stack trace:
#0 /home/ahbc/public_html/wp-content/plugins/woocommerce/includes/class-wc-data-store.php(149): WC_Booking_Data_Store->read(Object(WC_Booking))
#1 /home/ahbc/public_html/wp-content/plugins/woocommerce-bookings/includes/data-objects/class-wc-booking.php(149): WC_Data_Store->read(Object(WC_Booking))
#2 /home/ahbc/public_html/wp-content/plugins/ahbc-website-tweaks/ahbc-website-tweaks.php(104): WC_Booking->__construct(2223)
#3 /home/ahbc/public_html/wp-includes/class-wp-hook.php(288): auto_change_booking_status_to_paid(2223)
#4 /home/ahbc/public_html/wp-includes/class-wp-hook.php(310): WP_Hook->apply_filters('', Array)
#5 /home/ahbc/public_html/wp-includes/plugin.php(453): WP_Hook->do_action(Array)
#6 /home/ahbc/public_html/wp-content/plugins/woocommerce/includes/class-wc-order.php(327): do_action('woocommerce_ord...', 2223, Object(WC_Order))
# in /home/ahbc/public_html/wp-content/plugins/woocommerce-bookings/includes/data-stores/class-wc-booking-data-store.php on line 83

我也试过这个,但它似乎什么也没做:

function sv_wc_order_statuses_needs_payment( $statuses, $order ) {
    // use your custom order status slug here
    $statuses[] = 'pool-payment-rec';
    return $statuses;
}
add_filter( 'woocommerce_valid_order_statuses_for_payment_complete', 'sv_wc_order_statuses_needs_payment', 10, 2 );

我的参考资料:

woocommerce booking status changes woocommerce order status

Change Woocommerce order status for Cash on delivery

https://gist.github.com/bekarice/e922e79bc40eb0729095abc561cfe621

编辑:还尝试了以下几种变体:

add_action( 'woocommerce_order_status_changed', 'auto_change_booking_status_to_paid' );

function auto_change_booking_status_to_paid( $order_id ) {
    if( ! $order_id ) return;   

    $order = wc_get_order($order_id);
    $booking = get_wc_booking($booking_id);

    if( $order->get_status() == 'test' )
//  $order_id = $booking->get_order_id();
    $booking->update_status('confirmed', 'order_note');
}

【问题讨论】:

  • 你走在了正确的道路上,但是当你设置一个新的状态 $statuses[] = 'pool-payment-rec';它应该是 $statuses['pool-payment-rec'] = 'Payment Received'。 slug 需要设置为数组键。

标签: php wordpress woocommerce hook-woocommerce woocommerce-bookings


【解决方案1】:

好的,这是不需要任何自定义书面查询但使用 WooCommerce 预订插件中可用的适当方法的解决方案。

add_action('woocommerce_order_status_pool-payment-rec', 'auto_change_booking_status_to_paid', 20, 2 );

function auto_change_booking_status_to_paid( $order_id, $order ) {

    if( $order->get_status() === 'pool-payment-rec' ) {
        foreach( $order->get_items() as $item_id => $item ) {
            $product = wc_get_product($item['product_id']);
            if( $product->get_type() === 'booking' ) {
                $booking_ids = WC_Booking_Data_Store::get_booking_ids_from_order_item_id( $item_id );

                foreach( $booking_ids as $booking_id ) {
                    $booking = new WC_Booking($booking_id);

                    if( $booking->get_status() != 'paid' )
                        $booking->update_status( 'paid', 'order_note' );
                }

            }
        }
    }
}

【讨论】:

  • 我很想说这行得通,但唉,不行。从好的方面来说,它没有导致致命错误。
  • 您需要先将自定义状态添加到允许的预订状态列表中。我已将此添加到答案中,一旦你这样做,钩子 woocommerce_booking_pool-payment-rec 就会触发。
  • @AndrewSchultz 所以过滤器在添加自定义预订状态方面非常有效,尽管这只是一个问题。但是自定义订单状态 -> 预订状态仍然不起作用。我可能只是对如何实现它感到困惑。
  • @RoseFisher 我进入了一个预订订单,并将订单保存为自定义的“已收到池付款”状态。当页面重新加载时,它会显示“已付费”状态。你没看到这个吗?
  • @AndrewSchultz 我添加了动作和过滤器。结果是我有一个“收到池付款”的自定义预订状态。但是将订单状态从任何更改为“已收到池付款”并没有将预订状态更改为“已付款”(或自定义预订状态)。但同样,我可能会感到困惑或遗漏一些东西。(我累了,有可能影响认知功能的残疾)。
【解决方案2】:

您需要在此挂钩中首先从订单 ID 中获取预订 ID。然后,您将能够将预订状态更新为“已付款”,而不会出现任何错误。

我测试了另一种自定义状态,而不是您的自定义状态,它可以工作...... 如果我使用你的代码,我会得到和你一样的错误。

在下面的代码中,我使用了一个非常简单的查询来从订单 ID 中获取预订 ID,就像 WC_Order 方法所做的那样......

代码:

// Utility function to get the booking ID from the Order ID
function get_The_booking_id( $order_id ){
    global $wpdb;
    return $wpdb->get_var("SELECT ID FROM {$wpdb->prefix}posts WHERE post_parent = '$order_id'");
}

// On custom order status change, update booking status to "paid"
add_action('woocommerce_order_status_pool-payment-rec', 'auto_change_booking_status_to_paid', 20, 2 );
function auto_change_booking_status_to_paid( $order_id, $order ) {

    // Get the booking ID from the order ID
    $booking_id = get_The_booking_id( $order_id );

    if( empty($booking_id) )
        return; // Exit

    // Get an instance of the WC_Booking object
    $booking = new WC_Booking( $booking_id );

    // Update status
    if( $booking->get_status() != 'paid' )
        $booking->update_status( 'paid', 'order_note' );
}

代码进入您的活动子主题(或主题)的 function.php 文件中。经过测试并且可以工作。

【讨论】:

  • @LoicTheAztec 更正您的代码确实有效,谢谢。然而,正如 Andrew 所指出的,它使用了我非常希望避免的数据库查询。 Woocommerce 和 Bookings 显然有一个现有的钩子来使这项工作使用默认订单状态“处理中”或“完成”,预订状态更改为“已付款”。我只是不知道如何对自定义订单状态做同样的事情。
  • @RoseFisher 那么最后你是怎么做到的呢?只是好奇。谢谢。
  • 您在上面发布的代码运行良好,这就是我在尝试让 WooCommerce 的挂钩工作之间一直使用的代码。一段时间以来,我一直在用头撞他们,现在我准备放弃了。
猜你喜欢
  • 2017-05-24
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
  • 2018-01-01
  • 2019-02-01
  • 2022-09-30
相关资源
最近更新 更多