WooCommerce-将多个项目拆分为单独的行项目

时间:2018-05-30 作者:HectorOfTroy407

我希望在收到订单后,将数量大于1的行项目拆分为单独的行项目。我读了很多关于这方面的书,看到了很多在签出过程发生之前做这件事的好脚本,比如https://businessbloomer.com/woocommerce-display-separate-cart-items-product-quantity-1/https://stackoverflow.com/questions/32485152/woocommerce-treat-cart-items-separate-if-quantity-is-more-than-1?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa.

订单完成后,有人有没有想过该怎么做?还是在WooCommerce中创建订单?我想把任何数量大于1的东西分成单独的行项目。

所以我认为我需要访问所有行项目,然后找到数量大于1的行项目,然后添加新的行项目并减少数量,直到所有项目都平衡。我需要一些帮助的地方是如何创建行项目?我知道我可以检查它们,如下所示:

function inspect_line_items() 
{
  $order = wc_get_order( 390 );
    foreach ($order->get_items() as $item_id => $item_data) {

    // Get an instance of corresponding the WC_Product object
    $product = $item_data->get_product();
    $product_name = $product->get_name(); // Get the product name

    $item_quantity = $item_data->get_quantity(); // Get the item quantity

    $item_total = $item_data->get_total(); // Get the item line total

    // Displaying this data (to check)
    if ($item_quantity >1 ){
        echo \'HALP!\';

      }
    }
}
好的,我正在继续尝试,我已经能够添加行项目(这不是prod,只是测试它,显然这有一些差距:))。这就是说,我可以在结帐后添加一个新项目,然后使用另一个挂钩将订单状态更改回处理状态。现在的问题是显示的价格。即使我减少了特定项目的数量,它仍将显示全部/原始成本。我尝试更新sub\\u total和total字段,然后我得到了这个时髦的折扣:行项目。有什么想法吗?我是这里的正确人选吗?

add_action( \'woocommerce_checkout_create_order\', \'change_total_on_checking\', 20, 1 );
function change_total_on_checking( $order ) {
    // Get order total
    $total = $order->get_total();
    $items = $order->get_items();
    foreach ($order->get_items() as $item_id => $item_data) {

    // Get an instance of corresponding the WC_Product object
        $product = $item_data->get_product();
        $product_id = $item_data->get_id();
        $product_name = $product->get_name();
        $price = $product->get_price();


        $item_quantity = $item_data->get_quantity();
        $item_data[\'quantity\'] = $item_data[\'quantity\'] - 1 ; // Get the item quantity
        //$item_data[\'total\'] = $item_data[\'total\'] - $price;
        //$item_data[\'sub_total\'] = $item_data[\'sub_total\'] - $price;

        $item_total = $item_data->get_total(); // Get the item line total


        //do_action(\'woocommerce_add_to_order\', $item_data[\'id\'], $item_data[\'product_id\'], $item_quantity, $item_data[\'variation_id\']);
        WC()->cart->add_to_cart( $product_id, $item_quantity );
        $order->add_product( $product, 1);
        $order->calculate_totals(); // updating totals

        $order->save(); // Save the order data


    }

}

add_action( \'woocommerce_thankyou\', \'woocommerce_thankyou_change_order_status\', 10, 1 );
function woocommerce_thankyou_change_order_status( $order_id ){
    if( ! $order_id ) return;

    $order = wc_get_order( $order_id );

    $order->update_status( \'processing\' );
}

3 个回复
最合适的回答,由SO网友:HectorOfTroy407 整理而成

因此,我最终结合了一些答案,并在添加到购物车以及更新购物车时拆分了订单。下面的内容可以工作,尽管它只是一个前端定制。希望这对其他人有帮助!

function bbloomer_split_product_individual_cart_items( $cart_item_data, $product_id ){
  $unique_cart_item_key = uniqid();
  $cart_item_data[\'unique_key\'] = $unique_cart_item_key;
  return $cart_item_data;
}

add_filter( \'woocommerce_add_cart_item_data\', \'bbloomer_split_product_individual_cart_items\', 10, 2 );  

add_action( \'woocommerce_after_cart_item_quantity_update\', \'limit_cart_item_quantity\', 20, 4 );
function limit_cart_item_quantity( $cart_item_key, $quantity, $old_quantity, $cart ){

    // Here the quantity limit
    $limit = 1;
    $orders_added = $quantity - $limit;

    if( $quantity > $limit ){
        //Set existing line item quantity to the limit of 1
        $cart->cart_contents[ $cart_item_key ][\'quantity\'] = $limit;
        //get product id of item that was updated
        $product_id = $cart->cart_contents[ $cart_item_key ][ \'product_id\' ];

        for( $i = 0; $i< $orders_added; $i++ ){
            //iterate over the number of orders you must as with quantity one
            $unique_cart_item_key = uniqid();
            //create unique cart item ID, this is what breaks it out as a separate line item
            $cart_item_data = array();
            //initialize cart_item_data array where the unique_cart_item_key will be stored
            $cart_item_data[\'unique_key\'] = $unique_cart_item_key;
            //set the cart_item_data at unique_key = to the newly created unique_key

            //add that shit! this does not take into account variable products

            $cart->add_to_cart( $product_id, 1, 0, 0, $cart_item_data );

        }

        // Add a custom notice
        wc_add_notice( __(\'We Split out quantities of more than one into invididual line items for tracking purposes, please update quantities as needed\'), \'notice\' );
    }
}

SO网友:froger.me

以下是我找到的解决方案-拆分在订单保存时完成,而不是在购物车级别完成:

add_action( \'woocommerce_after_order_object_save\', array( $this, \'split_order_items\' ), 10, 2 );
function split_order_items( $order, $data_store ) {
    $order_items = $order->get_items();

    foreach ( $order_items as $item ) {

        if ( $item instanceof WC_Order_Item_Product ) {
            $quantity = $item->get_quantity( \'edit\' );
            $product  = $item->get_product();

            if ( $product && 1 < $quantity ) {
                $product = $item->get_product();
                $taxes   = $item->get_taxes();

                WP_Weixin::log( $order->get_item( $item->get_id() ) );

                $order->remove_item( $item->get_id() );

                for ( $i = $quantity; $i > 0; $i-- ) {
                    $new_item  = new WC_Order_Item_Product();
                    $new_taxes = array();

                    if ( ! empty( $taxes ) && is_array( $taxes ) ) {
                        foreach ( $taxes as $taxes_key => $tax_values ) {
                            $new_tax_values = array();

                            if ( ! empty( $values ) && is_array( $values ) ) {

                                foreach ( $values as $tax_key => $tax_value ) {
                                    $new_tax_values[ $tax_key ] = $tax_value / $quantity;
                                }
                            }

                            $new_taxes[ $taxes_key ] = $new_tax_values;
                        }
                    }

                    $new_item->set_product( $product );
                    $new_item->set_backorder_meta();
                    $new_item->set_props(
                        array(
                            \'quantity\'     => 1,
                            \'subtotal\'     => $item->get_subtotal( \'edit\' ) / $quantity,
                            \'total\'        => $item->get_total( \'edit\' ) / $quantity,
                            \'subtotal_tax\' => $item->get_subtotal_tax( \'edit\' ) / $quantity,
                            \'total_tax\'    => $item->get_total_tax( \'edit\' ) / $quantity,
                            \'taxes\'        => $new_taxes,
                        )
                    );
                    $order->add_item( $new_item );
                }
            }
        }
    }

    remove_action( \'woocommerce_after_order_object_save\', array( $this, \'split_order_items\' ), 10 );
    $order->save();
    add_action( \'woocommerce_after_order_object_save\', array( $this, \'split_order_items\' ), 10, 2 );
}
次要的缺点是订单保存了两次(订单项受到保护,必须先保存在数据库中才能访问),这是可以接受的,具体取决于具体情况。在花了几个小时查看源代码之后,这是我所知的唯一方法。

SO网友:Steven7

我读了很多以前的代码,我修复了这个,完全后端成本化,我需要这样的东西,我们在每个产品上添加序列号,但我们希望客户能按数量购买,希望对一些人有所帮助,

外接程序功能。主题/子主题或函数中包含的任何文件的php。php

在上一版中,我添加了对变体产品的支持

add_action( \'woocommerce_after_order_object_save\', \'split_order_items\', 10, 2 );
function split_order_items($order) {
    $order_items = $order->get_items();
    foreach ($order_items as $item) {
        $quantity = $item->get_quantity(\'edit\');
        $product = $item->get_product();
        $included_cats = [24, 25];
        $variable = false;
        if ($product->is_type(\'variation\')) {
            $variation_id = $product->get_id();
            $variable_prod = $product;
            $product = wc_get_product($product->get_parent_id());
            $variable = true;
        }
        $category_id = get_the_terms($product->get_id(), \'product_cat\')[0]->term_id;
        if ($product && $quantity > 1 && in_array($category_id, $included_cats)) {
            if ($variable) {
                $init_qty = $quantity;
                $item->set_quantity(1);
                if ($quantity > 1) $item->set_props([
                    \'subtotal\' => $item->get_subtotal(\'edit\') / ($init_qty ?: $quantity),
                    \'total\' => $item->get_total(\'edit\') / ($init_qty ?: $quantity),
                    \'subtotal_tax\' => $item->get_subtotal_tax(\'edit\') / ($init_qty ?: $quantity),
                    \'total_tax\' => $item->get_total_tax(\'edit\') / ($init_qty ?: $quantity),
                ]);
                if ($quantity == 1) continue;
                $quantity--;
            } else {
                $order->remove_item($item->get_id());
            }
            $taxes = $item->get_taxes();
            for ($i = $quantity; $i > 0; $i--) {
                $new_item = new WC_Order_Item_Product();
                $new_taxes = [];
                if ($variable) {
                    $new_item->set_product_id($product->get_parent_id());
                    $new_item->set_variation_id($variation_id);
                    $new_item->set_variation(is_callable([$variable_prod, \'get_variation_attributes\']) ? $variable_prod->get_variation_attributes() : []);
                    $new_item->set_name($variable_prod->get_name());
                    $new_item->set_tax_class($variable_prod->get_tax_class());
                } else {
                    $new_item->set_product($product);
                }
                if (!empty($taxes) && is_array($taxes)) {
                    foreach ($taxes as $taxes_key => $tax_values) {
                        $new_tax_values = [];
                        if (!empty($tax_values) && is_array($tax_values)) {
                            foreach ($tax_values as $tax_key => $tax_value) {
                                $new_tax_values[$tax_key] = $tax_value / $quantity;
                            }
                        }
                        $new_taxes[$taxes_key] = $new_tax_values;
                    }
                }
                $new_item->set_backorder_meta();
                $new_item->set_props([
                    \'quantity\' => 1,
                    \'subtotal\' => $item->get_subtotal(\'edit\') / ($variable ? 1 : $quantity),
                    \'total\' => $item->get_total(\'edit\') / ($variable ? 1 : $quantity),
                    \'subtotal_tax\' => $item->get_subtotal_tax(\'edit\') / ($variable ? 1 : $quantity),
                    \'total_tax\' => $item->get_total_tax(\'edit\') / ($variable ? 1 : $quantity),
                    \'taxes\' => $new_taxes,
                ]);
                $order->add_item($new_item);
            }
        }
    }
    remove_action(\'woocommerce_after_order_object_save\', \'split_order_items\', 10);
    $order->save();
    add_action(\'woocommerce_after_order_object_save\', \'split_order_items\', 10, 1);
}

结束

相关推荐