【问题标题】:Update Order Programmatically Doesn't Update Totals以编程方式更新订单不会更新总计
【发布时间】:2020-03-01 03:02:15
【问题描述】:

我正在尝试更新订购产品的数量,并且在这样做时我希望订单能够反映实际成本。我发现发生的是产品成本降低以匹配总数,并且订单总数从未实际更新。我在下面提供了一个简单的示例:

function prefix_update_woo_order() {

    $order_id       = 123; // This needs to be a real order or there will be errors
    $order_item_id  = 5; // This needs to be a real order item ID or there will be errors.

    $order       = new WC_Order( $order_id );
    $order_items = $order->get_items();
    $order_items[ $order_item_id ]->set_quantity( 2 );

    $order->calculate_taxes();
    $order->calculate_totals();
    $order->save();

}
add_action( 'admin_init', 'prefix_update_woo_order' );

例如,“带有徽标的豆豆”产品售价 18.00 美元,我最初购买 1 个。我想在下订单后以编程方式将订单商品的数量更新为 2 个,而不是 1 个。我预计总价为 36.00 美元,但我发现产品成本会发生变化以匹配总价。数量更新为 2 个,成本降至 9.00 美元,而不是“带徽标豆豆”的 18.00 美元。

简而言之,我想做的是更新现有订单商品数量并更新总计以反映新的数量成本、折扣、税费。我需要使用什么方法来实现这一点?

【问题讨论】:

    标签: wordpress woocommerce


    【解决方案1】:

    你好,我认为这段代码会改变你的问题

    add_action( 'admin_init', 'test_order_update_order' );
    function test_order_update_order() {
        $order_id       = 80; // This needs to be a real order or there will be errors
        $order_item_id  = 11; // This needs to be a real order item ID or there will be errors.
        $quantity = 2;  //quantity which you want to set.
        $order       = new WC_Order( $order_id );
        $order_items = $order->get_items();
        foreach ( $order_items as $key => $value ) {
            if ( $order_item_id == $key ) {
               $product_value = $value->get_data();
               $product_id    = $product_value['product_id']; 
            }
        }
        $product = wc_get_product( $product_id );
        $price = $product->get_price();
        $price = ( int ) $quantity * $price;
        $order_items[ $order_item_id ]->set_quantity( 2 );
        $order_items[ $order_item_id ]->set_subtotal( $price );
        $order->calculate_taxes();
        $order->calculate_totals();
        $order->save();
    }
    

    【讨论】:

    • 使用类似$total = wc_get_price_excluding_tax( $product, array( 'qty' => $line_item->get_quantity() ) ); 的东西可能是一个更好的解决方案,因为$price 可能并不总是以整数结尾——它可能是一个浮点数。
    【解决方案2】:

    我以前没有尝试过您想要实现的目标。我在您的代码中看到的是$order_items 是从WC_Order::get_items() 生成的项目对象数组,但我没有看到 WC_Order 实例被通知订单项目已更改。我希望像$order->update_cart($order_items); 这样的方法我相信我找到了一些有用的链接以进行更多研究 https://hotexamples.com/examples/-/WC_Order/-/php-wc_order-class-examples.html woocommerce - programmatically update cart item quantity

    对不起,我帮不上什么忙!

    【讨论】:

      【解决方案3】:

      使用下面的代码sn-p来完成上面的任务-

      function prefix_update_woo_order() {
      
          $order_id       = 123; // This needs to be a real order or there will be errors
          $order_item_id  = 5; // This needs to be a real order item ID or there will be errors.
      
          $order       = wc_get_order( $order_id );
          if( $order && !wc_get_order_item_meta( $order_item_id, '_order_item_data_updated', true ) ) {
              $item_price = wc_get_order_item_meta( $order_item_id, '_line_total', true );
              $updated_item_quantity = 2;
              wc_update_order_item_meta( $order_item_id, '_qty', $updated_item_quantity );
              wc_update_order_item_meta( $order_item_id, '_line_total', $item_price * $updated_item_quantity );
      
              $order->calculate_totals();
              $order->save();
              // set flag
              wc_add_order_item_meta( $order_item_id, '_order_item_data_updated', true, true );
          }
      
      }
      add_action( 'admin_init', 'prefix_update_woo_order' );
      

      代码转到您的活动主题的functions.php

      【讨论】:

        【解决方案4】:

        这就是我想出的。我尝试在适用的情况下使用wc_format_decimal()。简单地更新订单商品数量似乎需要做很多工作,但它就是这样。

        底部注释是不必要的,但如果您使用的是Cost of Goods plugin,那么它会解决这个问题。

        /**
         * Update the order item quantity and totals
         * @param Integer $order_id
         * @param Integer $order_item_id
         * @param Integer $quantity         - Quantity to set
         * 
         * @return void
         */
        function prefix_update_woo_order( $order_id, $order_item_id, $quantity ) {
        
            // Get Order, Item, and Product Data
            $order          = new WC_Order( $order_id );
            $order_items    = $order->get_items();
            $line_item      = $order_items[ $order_item_id ];
            $variation_id   = $line_item->get_variation_id();
            $product_id     = $line_item->get_product_id();
            $product        = wc_get_product( $variation_id ? $variation_id : $product_id );
            $quantity_old   = $line_item->get_quantity();
        
            // Calculate Old and New Discounts
            $discount = wc_format_decimal( $line_item->get_subtotal() - $line_item->get_total(), '' );
            if( ! empty( $discount ) ) {
                $discount_per_qty = wc_format_decimal( ( $discount / $quantity_old ), '' );
                $discount = wc_format_decimal( ( $discount_per_qty * $quantity ), '' );
            }
        
            // Set Quantity and Order Totals
            $line_item->set_quantity( $quantity );
            $total = wc_get_price_excluding_tax( $product, array( 'qty' => $line_item->get_quantity() ) );  // Also see `wc_get_price_excluding_tax()`
            $line_item->set_subtotal( $total );             // Without Discount
            $line_item->set_total( $total - $discount );    // With Discount
        
            // Save Everything
            $line_item->save();
            wc_save_order_items( $order_id, $order_items );
        
            /**
             * If using the 'Cost of Goods' Plugin
             * - - - - - -
             * $cog         = $line_item->get_meta( '_wc_cog_item_cost', true );
             * $new_cog     = wc_format_decimal( ( $quantity * $cog ), '' );
             * $line_item->update_meta_data( '_wc_cog_item_total_cost', $new_cog );
             * wc_cog()->set_order_cost_meta( $order_id, true );
             */
        
        }
        

        【讨论】:

          猜你喜欢
          • 2013-03-19
          • 2016-10-17
          • 2017-01-27
          • 1970-01-01
          • 1970-01-01
          • 2012-06-06
          • 1970-01-01
          • 1970-01-01
          • 2014-04-28
          相关资源
          最近更新 更多