【问题标题】:WooCommerce: Creating an order programmatically with a variable productWooCommerce:使用可变产品以编程方式创建订单
【发布时间】:2015-12-09 03:44:12
【问题描述】:

我正在尝试以编程方式创建订单。使用wc_create_order() 这非常简单:

$myProduct = new WC_Product(100);
$order = wc_create_order();
$order->add_product($myProduct, 1);
$order->calculate_totals();

这按预期工作,并为 ID 100 的简单产品创建了正确数量的订单。

但是,如果我尝试使用变体执行此操作,它的行为似乎不正确。经过多次试验和错误,我得到了某种这样的工作方式:

$membershipProduct = new WC_Product_Variable(100);
$theMemberships = $membershipProduct->get_available_variations();

$trueProduct = new WC_Product(100);

$variationsArray = array();

foreach ($theMemberships as $membership) {
    if ($membership['sku'] == $chosenVariation) {
        $variationID = $membership['variation_id'];
        $variationsArray = $membership['attributes'];
    }
}

if ($variationID) {
    $trueProduct->variation_id = $variationID;
}

$order = wc_create_order();
$order->add_product($trueProduct, 1, $variationsArray);
$order->calculate_totals();

但是,尽管它确实使用正确的产品和正确的变体 ID 创建了订单,但订单的总和始终为 0(巧合的是,它是第一个变体的价格)。

最初我尝试使用从new WC_Product_Variable() 创建的对象来使用$order->add_product(),但这导致订单中根本没有添加任何产品,这让我相信以编程方式使用可变产品创建订单存在问题。但是,按照这些调用的 WooCommerce 源代码,我看不出我做错了什么。

是否有我遗漏的东西,或者有更好的方法来创建具有可变产品的订单?

【问题讨论】:

  • 我不知道完整的答案,但你肯定错过了add_product( $product, $qty = 1, $args = array() ) 的第三个参数。您需要通过$args = array('variation' => $something );。我还不确定$something 需要如何格式化。
  • @helgatheviking 啊,你说得很对:我将数组作为第三个参数传递(在第二个示例中),但我没有注意到它需要'variation' 键。我已经添加了 ($variationsArray['variation'] = $membership['attributes'];),现在该商品在订单中显示为“正确”(例如,它是正确产品的正确变体),但价格仍然错误。不知道我错过了什么!

标签: php wordpress woocommerce


【解决方案1】:

解决了。

尽管我可以发誓我已经尝试过(但失败了)这样做,但答案是不添加 parent 产品(示例中为$trueProduct),而是添加 ID的变体产品。

这可能之前失败了,因为正如@helgatheviking 所指出的,我的$variationsArray 根据source 的格式不正确;我需要一个带有['variation'] 键的数组来发送正确的属性变体数组。

总的来说,我的工作代码现在看起来像这样:

$membershipProduct = new WC_Product_Variable(100);
$theMemberships = $membershipProduct->get_available_variations();

$variationsArray = array();

foreach ($theMemberships as $membership) {
    if ($membership['sku'] == $chosenVariation) {
        $variationID = $membership['variation_id'];
        $variationsArray['variation'] = $membership['attributes'];
    }
}

if ($variationID) {
    $varProduct = new WC_Product_Variation($variationID);

    $order = wc_create_order();
    $order->add_product($varProduct, 1, $variationsArray);
    $order->calculate_totals();
}

【讨论】:

  • 你想出来真是太酷了。我记得要求常规添加到购物车支持通过变体 id 直接添加并被拒绝,所以从来没有想过这样做。
  • @helgatheviking 实际上我不得不为几个不同的项目使用几种不同的方法,包括直接通过 AJAX 添加变体(类似于您提到的方式)。我需要把这个加入书签,否则我下次肯定会忘记怎么做。
  • 这是第三次这个确切的答案对我有用。如果我能再次支持你的答案就好了。
【解决方案2】:

如果你已经有了variation_id,你可以这样做

$product_variation = new WC_Product_Variation($variation_id);
$order = wc_create_order();
$args=array();
foreach($product_variation->get_variation_attributes() as $attribute=>$attribute_value){
        $args['variation'][$attribute]=$attribute_value;
}
$order->add_product($product_variation, $product['quantity'], $args);

【讨论】:

    【解决方案3】:

    这是对我有用的解决方案:

    function add_item_to_order( $order_id, $prod_id ) {
    
        $order      = wc_get_order( $order_id );
        $_product   = wc_get_product( $prod_id ); 
    
        // Set values
        $item = array();
        $item['product_id']        = $_product->id;
        $item['variation_id']      = isset( $_product->variation_id ) ? $_product->variation_id : '';
        $item['variation_data']    = $item['variation_id'] ? $_product->get_variation_attributes() : '';
        $item['name']              = $_product->get_title();
        $item['tax_class']         = $_product->get_tax_class();
        $item['qty']               = 1;
        $item['line_subtotal']     = wc_format_decimal( $_product->get_price_excluding_tax() );
        $item['line_subtotal_tax'] = '';
        $item['line_total']        = wc_format_decimal( $_product->get_price_excluding_tax() );
        $item['line_tax']          = '';
        $item['type']              = 'line_item';
    
        // Add line item
        $item_id = wc_add_order_item( $order_id, array(
            'order_item_name'       => $item['name'],
            'order_item_type'       => 'line_item'
        ) );
    
        // Add line item meta
        if ( $item_id ) {
            wc_add_order_item_meta( $item_id, '_qty', $item['qty'] );
            wc_add_order_item_meta( $item_id, '_tax_class', $item['tax_class'] );
            wc_add_order_item_meta( $item_id, '_product_id', $item['product_id'] );
            wc_add_order_item_meta( $item_id, '_variation_id', $item['variation_id'] );
            wc_add_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] );
            wc_add_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] );
            wc_add_order_item_meta( $item_id, '_line_total', $item['line_total'] );
            wc_add_order_item_meta( $item_id, '_line_tax', $item['line_tax'] );
            wc_add_order_item_meta( $item_id, '_line_tax_data', array( 
                                                                        'total' => array(), 
                                                                        'subtotal' => array() ) 
                                                                     );
            // Store variation data in meta
            if ( $item['variation_data'] && is_array( $item['variation_data'] ) ) {
                foreach ( $item['variation_data'] as $key => $value ) {
                    wc_add_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value );
                }
            }
    
        }
    
        $item['item_meta']       = $order->get_item_meta( $item_id );
        $item['item_meta_array'] = $order->get_item_meta_array( $item_id );
        $item                    = $order->expand_item_meta( $item );
        $order->calculate_totals();
    }
    

    【讨论】:

    • 嗨@Tyler 它给了我Fatal error: Call to a member function get_title() on a non-object 的错误。你能帮我解决这个问题吗?
    猜你喜欢
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2017-09-13
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多