【问题标题】:Modify product price in WooCommerce cart修改 WooCommerce 购物车中的产品价格
【发布时间】:2017-08-07 10:01:20
【问题描述】:

我有一家商店,如果批量购买产品,我们会打折(批量优惠因产品而异)。该部分已排序。

目前,我使用这样的负费用申请折扣:

function sale_custom_price($cart_object) { 
  foreach ($cart_object->cart_contents as $p) {
    $prod_id = $p['product_id'];
    $prod_n = $p['quantity'];
    $prod_price = $p['data']->price;
    $prod_name = $p['data']->post->post_title;
    $prod_total = $p['line_total'];

    /*
    calc_discount: NULL for no discount for this product
                   else
                     array(
                      n => how many are required, e.g. 12
                      free_pcs_deal => how many of these should be free, e.g. 1
                     )
    */
    $discount = calc_discount($prod_id, $prod_n);

    if (is_null($discount)) {
      continue;
    }

    $discount_n = $discount['n'];
    $free_pcs_deal = $discount['free_pcs_deal'];

    if ($discount_n <= 0) {
      continue;
    }

    $discount_txt = $prod_name . ' (' . $discount_n . ' x ' . $free_pcs_deal . ' stk.)';
    $discount = -1 * $discount_n * $free_pcs_deal * $prod_price;

    $cart_object->add_fee('Rabat: ' . $discount_txt, $discount, true, '');
  }
}

add_action( 'woocommerce_cart_calculate_fees', 'sale_custom_price', 2, 1);

但这不受支持,并且在未来将变得不可能。因此,我想自动调整产品价格。

假设客户购买了12件产品A,正常价格是100,但是产品A有大宗交易买12,只付11(买11送1)。所以目前,产品价格为 12*100 = 1200,负费用为 100。所以所有 12 种产品 A 的平均产品价格为 11*100/12 = 91.67。我希望将其用于我的购物车。

但我无法让它在购物车中显示修改后的价格以及正确的 line_total 和 line_subtotal 以及订单总额。所以好像没找到合适的action/filter

我尝试过这样的事情:

$cart = WC()->cart->cart_contents;

foreach ($cart as $key => $p) {
  $custom_price = 111; // of course replaced by logic calculating the new, modified price
  WC()->cart->cart_contents[$key]['data']->price = $custom_price;
}

我已经在woocommerce_cart_updatedwoocommerce_before_cart_contentswoocommerce_add_to_cart 和其他人中尝试过这种逻辑,但它不会显示正确的购物车以及更新的价格、line_total、订单总数等。

我可以通过woocommerce_cart_item_price钩子计算并显示更新后的价格,但这只是显示,不在业务逻辑中,所以所有总计都被修改了。

我做错了什么?

【问题讨论】:

    标签: woocommerce hook-woocommerce


    【解决方案1】:

    在计算总计之前尝试进行价格自定义。您可以使用此钩子“woocommerce_before_calculate_totals”并降低钩子的优先级,以便任何其他插件/自定义不会覆盖它。

    这是一段您可以根据需要自定义的代码:

    function calculate_custom_price( $cart_object ) {
    
        // Loop for all products in cart
        foreach ( $cart_object->cart_contents as $key => $value ) {
    
            if(isset($value['_custom_customized']) && !empty($value['_custom_customized']) && (!isset($isProcessed) || empty($isProcessed))) {
                $fltCustomPrice = 0.00;
                $quantity = intval( $value['quantity'] );
                $orgPrice = floatval( $value['data']->price );
    
                // For all sub products of build your own basket
                foreach($value['_custom_customized'] AS $keyInner => $arrValInner) {
                    $fltCustomPrice += floatval($arrValInner['price']) * floatval($arrValInner['quantity']);
                }
                $cart_object->cart_contents[$key]['data']->price = ( $orgPrice + $fltCustomPrice );
            }
        }
    }
    add_action( 'woocommerce_before_calculate_totals', 'calculate_custom_price', 2, 1 );
    

    【讨论】:

    • 它确实更新了购物车对象中的价格,但在显示购物车时不会更新 line_total 等。我用过这个: function calculate_custom_price($cart_object) { foreach ($cart_object->cart_contents as $key => $value) { $cart_object->cart_contents[$key]['data']->price = 5; } 回声 '
    【解决方案2】:
            function on_display_cart_item_price_html($html, $cart_item, $cart_item_key) {
    
                if (is_cart()) {
                    $price_adjusted = 10; // your adjustments here
                    $price_base = $cart_item['data']->sale_price;
                    if (!empty($price_adjusted)) {
                        if (intval($price_adjusted) > 0) {
                            $_qnty = $cart_item['quantity'];
                            $cart_item['data']->set_price($price_base - ($price_adjusted / $_qnty));
                            $html = '<del>' . wc_price($price_base) . '</del><ins> ' . wc_price($price_base - ($price_adjusted / $_qnty)) . '</ins>';
                        } else {
                            $html = '<span class="amount">' . wc_price($price_base) . '</span>';
                        }
                    }
                }
    
                return $html;
            }
    
    
    add_filter('woocommerce_cart_item_price', 'on_display_cart_item_price_html', 100, 3);
    
    
        function change_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart ) { 
            $cart_subtotal = 5;
            return $cart_subtotal; 
        }; 
        add_filter( 'woocommerce_cart_subtotal', 'change_woocommerce_cart_subtotal', 10, 3 ); 
    
    
        // define the woocommerce_order_amount_total callback 
        function change_woocommerce_order_amount_total( $order_total ) { 
    
            $order_total = 5;
            return $order_total; 
        }; 
        add_filter( 'woocommerce_cart_totals_order_total_html', 'change_woocommerce_order_amount_total' );
    

    在你的活动主题的functions.php中试试这个代码sn-p

    【讨论】:

    • 这只会更改打印的 html,不会更改购物车业务逻辑中的价格。
    • 谢谢,但我会覆盖所有逻辑(费用、运费、税金……)。因此,我需要要么重新实现它,要么在会话中保存给定的折扣,然后从提供的总数中减去它作为参数。这势必会出错。因此,最好的(最容错的)是在工作流程的早期更改产品价格,让 WooC 引擎像往常一样做。
    • 你可以使用这个钩子“woocommerce_get_price”
    • 它也不起作用,但查看代码似乎应该如此。我怀疑我的一个插件引起了麻烦,可能是因为我也在使用基于角色的定价。
    猜你喜欢
    • 2017-04-06
    • 1970-01-01
    • 2017-10-12
    • 2018-02-17
    • 2017-04-28
    • 2017-12-10
    • 2016-04-04
    • 2018-07-31
    • 2021-11-08
    相关资源
    最近更新 更多