donglu9134 2018-01-18 00:16
浏览 42
已采纳

自定义动态商品定价在Woocommerce Checkout上重置

I am having a problem getting my price updates to stick. More or less this is a sample of what I am using to update the prices:

    add_action( 'woocommerce_before_calculate_totals', 'cst_product_quantity_discounter', 10 );
function cst_product_quantity_discounter( $cart_object ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
        return;
    }

    if( ! isset( WC()->session->reload_checkout ) ) {

        // declare woocommerce global
        global $woocommerce;      

        // array of ID's to match that represent each item

        $special_ids_array = [
            0 => array( "id" => 15372, "product" => "TAF", "single_bag_price" => 42.99, "3_multiplier" => 0.82181902768 ),
            1 => array( "id" => 14285, "product" => "POW", "single_bag_price" => 29.99, "3_multiplier" => 0.8890741358 )
        ];

        // gather cart object
        $wc_cart = WC()->cart->get_cart();

        foreach( $wc_cart as $cart_item ){

            // gather relevant data for testing and comparisons
            $product_id = $cart_item['product_id'];
            $product_key = $cart_item['key'];
            $pack_size_attribute = $cart_item['variation']['attribute_pa_sample-check']; // returns: "full-pack" || "sample" || null
            $item_quantity = $cart_item['quantity'];

            foreach ( $special_ids_array as $id_test_2 ) {
                if ( $product_id === $id_test_2["id"] && $pack_size_attribute !== "sample" ){
                    foreach ( $cart_object->cart_contents as $key => $value ) {
                        // if the key matches we will set the price of the correct product
                        if ( $key === $product_key ){
                            $discounted_price = 10;
                            $value['data']->set_price($discounted_price);
                        }
                    }
                }
            } 
        }
    }
}

There is some other stuff to get the values seen but that works. this will update on my test cart page and everything looks fine.

My issue is when I go to my test checkout page the prices update briefly, then they are overwritten by the original price. I am missing some update thats being run on checkout and woocommerce_before_calculate_totals hook does not seem to be making a permanent change on the checkout page.

Where do I need to hook my function so the changes persist whatever loads are occurring on checkout that overwrite the initial successful price change?

  • 写回答

1条回答 默认 最新

  • duanji2014 2018-01-18 03:43
    关注

    There is some strange things in your code:

    • The $cart_object (that is the WC_Cart object) is already an argument in the hooked function (it replaces WC()->cart or outdated $woocommerce->cart )
    • So WC()->cart->get_cart() and $cart_object->cart_contents are exactly the same thing. The best is using $cart_object->get_cart() in your foreach loops.
    • You don't need global $woocommerce; as it's already included in WC() (the global Woocommerce object so already in $cart_object)
    • reload_checkout doesn't exist in WC_Sessions or WC_Session_Handler classes (so your condition is always true) and anyway this is not useful for this hook.
    • For info $cart_item['data'] is an instance of the WC_Product object for this cart item.
    • You are have 2 cart loops one in the other and you can make everything in one (it will avoid problems).
    • $cart_item['key'] and the $key (in the cart loop) are always the same thing. You will not really need to use it in this case…
    • You have removed completely the prices calculations in this new edit of your question and the pricing is not dynamic anymore (based on the product quantity like before).

    So I have tried to add back a kind of dynamic price calculation in more real conditions, but in a different way based on your $special_ids_array array keys/values.

    The calculated dynamic price discount start with a quantity of 3 by item that match the conditions (Product Ids et "pack size" attribute).

    So All this simplifies and compact a lot this revisited code:

    add_action( 'woocommerce_before_calculate_totals', 'custom_product_quantity_discounter', 10, 1 );
    function custom_product_quantity_discounter( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        // array of ID's to match that represent each item
        $special_ids = array(
            0 => array( "id" => 15372, "product" => "TAF", "single_bag_price" => 42.99, "3_multiplier" => 0.82181902768 ),
            1 => array( "id" => 14285, "product" => "POW", "single_bag_price" => 29.99, "3_multiplier" => 0.8890741358 ),
        );
    
        // Loop through the cart items
        foreach( $cart->get_cart() as $cart_item ){
            $product_id  = $cart_item['product_id'];
            $quantity    = $cart_item['quantity'];
            $pack_size   = $cart_item['variation']['attribute_pa_sample-check']; // returns "full-pack", "sample" or null
            foreach ( $special_ids as $special_id ){
                if( $special_id['id'] == $product_id && $pack_size !== 'sample' && $quantity >= 3 ){
                    $discounted_price = $special_id['single_bag_price'] * $special_id['3_multiplier']; // calculation (fake and custom)
                    $cart_item['data']->set_price($discounted_price); // set the calculated price
                }
            }
        }
    }
    

    Code goes in function.php file of the active child theme (or active theme).

    Tested and works.

    The dynamic calculated pricing based on cart item quantities and custom calculation persist in checkout even when reloading the page multiple times.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加
  • ¥15 用ns3仿真出5G核心网网元