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.

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

报告相同问题?

悬赏问题

  • ¥15 已知许多点位,想通过高斯分布来随机选择固定数量的点位怎么改
  • ¥15 怎么生成确定数目的泊松点过程
  • ¥15 layui数据表格多次重载的数据覆盖问题
  • ¥15 python点云生成mesh精度不够怎么办
  • ¥15 QT C++ 鼠标键盘通信
  • ¥15 改进Yolov8时添加的注意力模块在task.py里检测不到
  • ¥50 高维数据处理方法求指导
  • ¥100 数字取证课程 关于FAT文件系统的操作
  • ¥15 如何使用js实现打印时每页设置统一的标题
  • ¥15 安装TIA PortalV15.1报错