【问题标题】:Change order status for backordered items in Woocommerce在 Woocommerce 中更改延期交货商品的订单状态
【发布时间】:2018-07-14 05:24:24
【问题描述】:

我正在使用 WordPress 和 WooCommerce 配置网上商店。我安装了一个名为Woo Multi Order Creator 的插件。所做的是,每当订购超过 1 件商品时,它将主订单分为多个订单,每个购买的商品一个订单。

现在,如果每个订单中的商品包含值为“Backordered”的元键,我想做的是让它改变每个订单的订单状态。

例如,如果购买了产品 A 和产品 B。产品 A 缺货,因此有 {$wpdb->prefix}woocommerce_order_itemmeta.meta_key = 'Backordered' 并且产品 B 将有库存,并且它没有用于延期交货的元密钥。

现在,插件将此订单分为两个订单,每个购买的商品一个。我希望它进一步做的是查看每个新订单中包含的项目是否具有延期交货的元键,如果它已经将每个订单的订单状态更改为“等待”。

插件代码:

    <?php /*
Plugin Name: Woo Product Wise Multi Order Creator
Description: Create multiple orders in woocommerce product wise.
Plugin URI: http://www.thewpexperts.co.uk
Version: 2.0.0
Author: TheWPexperts 
Author URI: http://www.thewpexperts.com/ 
*/

 /*

    Copyright 2017  The WP Experts

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    Permission is hereby granted, free of charge, to any person obtaining a copy of this
    software and associated documentation files (the "Software"), to deal in the Software
    without restriction, including without limitation the rights to use, copy, modify, merge,
    publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
    to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or
    substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.

*/ 
define( 'WOO_MULTI_ORDER_URL', plugins_url('/', __FILE__) );
define( 'WOO_MULTI_ORDER_DIR', dirname(__FILE__) );
if ( ! class_exists( 'WC_CPInstallCheck' ) ) {
    class WC_CPInstallCheck {
        static function install() {
            if ( !is_plugin_active('woocommerce/woocommerce.php')){
                deactivate_plugins(__FILE__);
                $error_message = __('This plugin requires <a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a>  plugins to be active!', 'woocommerce');
                die($error_message);
            }
        }
    }
}
register_activation_hook( __FILE__, array('WC_CPInstallCheck', 'install') );
add_action('init','woo_multi_order_load_function');
function woo_multi_order_load_function() {
    $enableMultiOrder = get_option('enableMultiOrder'); 
    $customOrderPermit = get_option('customOrderPermit');   
    add_action('admin_menu', 'register_multi_order_setting_submenu',99);
    if($enableMultiOrder == 1){
        add_action('woocommerce_multiorder_checkout_before_order_info', 'destinationStep');
        add_action( 'woocommerce_thankyou', 'multi_order_generator', 10, 1 );
            if($customOrderPermit ==1){
            add_action( 'woocommerce_after_order_notes', 'woo_order_dates_checkout_field' ); 
            add_action( 'wp_head', 'date_picker_scripts' );
            add_action( 'woocommerce_checkout_update_order_meta', 'checkout_update_delivery_meta' );
            add_filter("manage_edit-shop_order_columns", "woo_order_extra_columns");
            add_action("manage_posts_custom_column",  "woo_order_extra_columns_content");
            add_filter( 'manage_edit-shop_order_sortable_columns', 'my_sortable_cake_column' );
        }
    }
} 
function your_plugin_settings_link($links) { 
  $settings_link = '<a href="admin.php?page=multi-order-setting">Settings</a>'; 
  array_unshift($links, $settings_link); 
  return $links; 
}
$plugin = plugin_basename(__FILE__); 
add_filter("plugin_action_links_$plugin", 'your_plugin_settings_link' );
function register_multi_order_setting_submenu() {
    add_submenu_page( 'woocommerce', 'Multi-order Setting', 'Multi-order Setting', 'manage_options', 'multi-order-setting', 'multi_order_setting' ); 
} 
function multi_order_setting(){
    include(WOO_MULTI_ORDER_DIR.'/admin/settings.php');
}
function date_picker_scripts() {
    $customOrderPermit = get_option('customOrderPermit');   
    if(is_page('checkout')){
      wp_enqueue_script( 'jquery' );
      wp_enqueue_script( 'jquery-ui-datepicker', array( 'jquery' ) );
      wp_register_style('jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');
      wp_enqueue_style( 'jquery-ui' );         
    }
}
function checkout_update_delivery_meta( $order_id ) {
    $dateArray = array();
    $customOrderPermit = get_option('customOrderPermit');   
    $dayDifference = get_option('dayDifference');   
    $dt = date('d/m/y', strtotime("+".$dayDifference." days"));
    if ( count($_POST['customDatePicker'])>0) {
        foreach($_POST['customDatePicker'] as $customDatePicker){
            if(!empty($customDatePicker)){
                $dateArray[]  = $customDatePicker;
            }else{
                $dateArray[]  = $dt;
            }
        }
    }
    $dateValue = join( ', ', $dateArray ); 
    update_post_meta( $order_id, 'Delivery_Dates', $dateValue);
} 
function woo_order_dates_checkout_field( $checkout ) {
    global $woocommerce,$orderRate;
    $customOrderPermit = get_option('customOrderPermit');   
    $dayDifference = get_option('dayDifference');   
    $dt = date('Y-m-d', strtotime("+".$dayDifference." days"));
    $items = $woocommerce->cart->get_cart();
    foreach($items as $item => $values) { 
        $_product = $values['data']->post; 
        $price = get_post_meta($values['product_id'] , '_price', true);
        echo "<b>".$_product->post_title."</b>&nbsp;&nbsp;";
        echo '<input type="text" class="deliveryDate" id="datepicker'.$_product->ID.'" name="customDatePicker[]" placeholder="Choose dates">'; ?> 
        <script type="text/javascript"> 
            jQuery(document).ready(function() {
                jQuery("#datepicker<?php echo $_product->ID;?>").datepicker({ 
                    dateFormat: 'dd/mm/yy', 
                    minDate: new Date('<?php echo $dt; ?>'),
                });
            });
        </script>   
        <?php 
    } 
}
function multi_order_generator($order_id) {
    $customOrderPermit = get_option('customOrderPermit');   
    $order = new WC_Order( $order_id );
    $items = $order->get_items();
    $count =0;
    $productID = array();
    $productQty = array();
    $deliveryDate = get_post_meta( $order_id, 'Delivery_Dates',true);
    $dateArray = explode(',',$deliveryDate);
    foreach($items as $order_item_id => $item){
        if($count >0){
            $productName = get_the_title($item['product_id']);
            $orderValueID = createNewOrderAndRecordPayment($order_id);
            addProductWithOrder($orderValueID,$item['product_id'],$item['qty']);
            if($customOrderPermit == 1){
                    update_post_meta($orderValueID,'_Delivery_Date',$dateArray[$count]);
            }
            wc_delete_order_item($order_item_id);
        }else{
            if($customOrderPermit == 1){
                    update_post_meta($order_id,'_Delivery_Date',$dateArray[0]);
            }
        }
        $count++;
    }
}
function addProductWithOrder($orderID,$productID,$productQty){
    $ProOrderItem = new WC_Order($orderID); 
    $ProOrderItem->add_product(get_product($productID),$productQty); 
}
function createNewOrderAndRecordPayment($orderID) {
    global $wpdb;
    global $woocommerce;
    $original_order = new WC_Order($orderID);
    $currentUser = wp_get_current_user();
    //1 Create Order
    $order_data =  array(
        'post_type'     => 'shop_order',
        'post_status'   => 'publish',
        'ping_status'   => 'closed',
        'post_author'   => $currentUser->ID, 
        'post_excerpt' => $original_order->customer_message, 
        'post_password' => uniqid( 'order_' )   // Protects the post just in case
    );
    $order_id = wp_insert_post( $order_data, true );
    if ( is_wp_error( $order_id ) ){
        $msg = "Unable to create order:" . $order_id->get_error_message();;
        throw new Exception( $msg );
    } else {
        $order = new WC_Order($order_id);
        //2 Update Order Header 
        update_post_meta( $order_id, '_order_shipping', get_post_meta($orderID, '_order_shipping', true) );
        update_post_meta( $order_id, '_order_discount', get_post_meta($orderID, '_order_discount', true) );
        update_post_meta( $order_id, '_cart_discount',  get_post_meta($orderID, '_cart_discount', true) );
        update_post_meta( $order_id, '_order_tax',              get_post_meta($orderID, '_order_tax', true) );
        update_post_meta( $order_id, '_order_shipping_tax',     get_post_meta($orderID, '_order_shipping_tax', true) );
        update_post_meta( $order_id, '_order_total',            get_post_meta($orderID, '_order_total', true) );

        update_post_meta( $order_id, '_order_key',              'wc_' . apply_filters('woocommerce_generate_order_key', uniqid('order_') ) );
        update_post_meta( $order_id, '_customer_user',          get_post_meta($orderID, '_customer_user', true) );
        update_post_meta( $order_id, '_order_currency',         get_post_meta($orderID, '_order_currency', true) );
        update_post_meta( $order_id, '_prices_include_tax',     get_post_meta($orderID, '_prices_include_tax', true) );
        update_post_meta( $order_id, '_customer_ip_address',    get_post_meta($orderID, '_customer_ip_address', true) );
        update_post_meta( $order_id, '_customer_user_agent',    get_post_meta($orderID, '_customer_user_agent', true) );

        //3 Add Billing Fields

        update_post_meta( $order_id, '_billing_city',           get_post_meta($orderID, '_billing_city', true));
        update_post_meta( $order_id, '_billing_state',          get_post_meta($orderID, '_billing_state', true));
        update_post_meta( $order_id, '_billing_postcode',       get_post_meta($orderID, '_billing_postcode', true));
        update_post_meta( $order_id, '_billing_email',          get_post_meta($orderID, '_billing_email', true));
        update_post_meta( $order_id, '_billing_phone',          get_post_meta($orderID, '_billing_phone', true));
        update_post_meta( $order_id, '_billing_address_1',      get_post_meta($orderID, '_billing_address_1', true));
        update_post_meta( $order_id, '_billing_address_2',      get_post_meta($orderID, '_billing_address_2', true));
        update_post_meta( $order_id, '_billing_country',        get_post_meta($orderID, '_billing_country', true));
        update_post_meta( $order_id, '_billing_first_name',     get_post_meta($orderID, '_billing_first_name', true));
        update_post_meta( $order_id, '_billing_last_name',      get_post_meta($orderID, '_billing_last_name', true));
        update_post_meta( $order_id, '_billing_company',        get_post_meta($orderID, '_billing_company', true));

        //4 Add Shipping Fields

        update_post_meta( $order_id, '_shipping_country',       get_post_meta($orderID, '_shipping_country', true));
        update_post_meta( $order_id, '_shipping_first_name',    get_post_meta($orderID, '_shipping_first_name', true));
        update_post_meta( $order_id, '_shipping_last_name',     get_post_meta($orderID, '_shipping_last_name', true));
        update_post_meta( $order_id, '_shipping_company',       get_post_meta($orderID, '_shipping_company', true));
        update_post_meta( $order_id, '_shipping_address_1',     get_post_meta($orderID, '_shipping_address_1', true));
        update_post_meta( $order_id, '_shipping_address_2',     get_post_meta($orderID, '_shipping_address_2', true));
        update_post_meta( $order_id, '_shipping_city',          get_post_meta($orderID, '_shipping_city', true));
        update_post_meta( $order_id, '_shipping_state',         get_post_meta($orderID, '_shipping_state', true));
        update_post_meta( $order_id, '_shipping_postcode',      get_post_meta($orderID, '_shipping_postcode', true));

        //6 Copy shipping items and shipping item meta from original order
        $original_order_shipping_items = $original_order->get_items('shipping');
        foreach ( $original_order_shipping_items as $original_order_shipping_item ) {
            $item_id = wc_add_order_item( $order_id, array(
                'order_item_name'       => $original_order_shipping_item['name'],
                'order_item_type'       => 'shipping'
            ) );
            if ( $item_id ) {
                wc_add_order_item_meta( $item_id, 'method_id', $original_order_shipping_item['method_id'] );
                wc_add_order_item_meta( $item_id, 'cost', wc_format_decimal( $original_order_shipping_item['cost'] ) );
            }
        }

        // Store coupons
        $original_order_coupons = $original_order->get_items('coupon');
        foreach ( $original_order_coupons as $original_order_coupon ) {
            $item_id = wc_add_order_item( $order_id, array(
                'order_item_name'       => $original_order_coupon['name'],
                'order_item_type'       => 'coupon'
            ) );
            // Add line item meta
            if ( $item_id ) {
                wc_add_order_item_meta( $item_id, 'discount_amount', $original_order_coupon['discount_amount'] );
            }
        }

        //Payment Info
        update_post_meta( $order_id, '_payment_method',         get_post_meta($orderID, '_payment_method', true) );
        update_post_meta( $order_id, '_payment_method_title',   get_post_meta($orderID, '_payment_method_title', true) );
        update_post_meta( $order->id, 'Transaction ID',         get_post_meta($orderID, 'Transaction ID', true) );
        $order->payment_complete();

        //6 Set Order Status to processing to trigger initial emails to end user and vendor
        $order->update_status('processing'); 
    }
    return $order_id;
}
function woo_order_extra_columns($columns)
{
   $newcolumns = array(
        "cb"            => "<input type  = \"checkbox\" />",
        "delivery"    => esc_html__('Delivery', 'woocommerce'),
    );
    $columns = array_merge($newcolumns, $columns);
    return $columns;
}
function woo_order_extra_columns_content($column)
{
    global $post;
    $order_id = $post->ID;
    switch ($column)
    {
        case "delivery":
        $daliveryDate = get_post_meta($order_id,'_Delivery_Date',true);
        if ( empty( $daliveryDate ) )
                echo __( '-' );
        else
            printf( __( '%s' ), $daliveryDate );
        break;
    }
}

function my_sortable_cake_column( $columns ) {
$columns['delivery'] = 'delivery';
    return $columns;
}

它在第 253 行将订单状态更改为正在处理。

我猜应该在这里添加一些代码以使其将订单状态更改为等待,如果订单中的项目具有延期交货的元密钥。

我希望比我非常有限的知识更专业的人能来帮助我。

【问题讨论】:

    标签: php sql wordpress woocommerce orders


    【解决方案1】:

    这是一个钩子函数,当订单获得“处理”状态时触发。

    在函数内部,我们通过简单的 SQL 查询从订单 ID 中查找“延期交货”的订单商品。

    如果发现“延期交货”商品,我们会将订单状态更改为“暂停”(您的情况下正确的订单状态)。

    代码:

    add_action('woocommerce_order_status_processing', 'pending_back_orders_to_on_hold', 60, 2 );
    function pending_back_orders_to_on_hold( $order_id, $order ) {
        global $wpdb;
    
        // The SQL query for Order items in backorder
        $results = $wpdb->get_col( "
            SELECT woim.meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim
            INNER JOIN {$wpdb->prefix}woocommerce_order_items as woi ON woim.order_item_id = woi.order_item_id
            WHERE woi.order_id = '$order_id' AND woim.meta_key = 'Backordered'
        " );
        
        // If an item is 'Backordered' we change the order status to "on-hold"
        if(reset($results) > 0)
            $order->update_status('on-hold');
    }
    

    代码进入您的活动子主题(或活动主题)的 function.php 文件中。

    经过测试并且有效。


    更新 (与您的评论有关)

    如果您想为此目的更改插件内的代码,您将替换第 253 行:

    $order->update_status('processing');
    

    通过以下代码:

    $line_item_ids = array_keys( $order->get_items() );
    $backordered = wc_get_order_item_meta( reset($line_item_ids), 'Backordered', true );
    $changed_status = $backorders > 0 ? 'on-hold' : 'processing';
    $order->update_status( $changed_status ); 
    

    应该可以,但这不是一个好习惯。

    【讨论】:

    • 非常感谢您帮助我!然而有一个问题。它不适用于我安装的插件。如果我下订单,它会暂停第一个订单,并从每个项目创建一个新订单,其中不止一个。也就是说,您的 sn-p 在插件将订单分成单独的订单之前工作。我想可以使用另一个钩子吗?在插件完成工作后,会在稍后的某个时间点将订单更改为暂停?
    • @clauden 没有其他钩子! woocommerce_order_status_processing 钩子仅在您的插件使用时触发:$order-&gt;update_status('processing');
    • 好的。它只是没有按应有的方式工作。如果我购买了 2 件延期交货的商品和 1 件库存商品,对于每个包含延期交货商品的订单,它不会始终将订单状态更改为暂停。我尝试将您的代码直接集成到插件代码中,但没有成功。您认为您可以将您的 sn-p 集成到插件代码中,以便它可以按预期工作吗?提前致谢!
    • @clauden 继续尝试,因为这是个好曲目……您也可以尝试要求作者在此处添加一个钩子,因为它可以轻松改变行为。
    猜你喜欢
    • 2020-08-05
    • 2017-07-23
    • 1970-01-01
    • 2018-08-01
    • 2017-05-24
    • 1970-01-01
    • 2018-10-14
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多